xref: /petsc/src/snes/interface/snes.c (revision fc8bc0e3f6e47c2b62b3560f801e64bdf70461bd)
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;
13*fc8bc0e3SRichard Tran Mills 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 
18c3339decSBarry Smith    Logically Collective
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21f6dfbefdSBarry Smith +  snes - iterative context obtained from `SNESCreate()`
22f6dfbefdSBarry Smith -  flg - `PETSC_TRUE` indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
2567b8a455SSatish Balay .  -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29f6dfbefdSBarry Smith    Note:
30f6dfbefdSBarry Smith    Normally PETSc continues if a solver fails to converge, you can call `SNESGetConvergedReason()` after a `SNESSolve()`
31f6dfbefdSBarry Smith    to determine if it has converged. Otherwise the solution may be inaccurate or wrong
32e113a28aSBarry Smith 
33f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
34e113a28aSBarry Smith @*/
35d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetErrorIfNotConverged(SNES snes, PetscBool flg)
36d71ae5a4SJacob Faibussowitsch {
37e113a28aSBarry Smith   PetscFunctionBegin;
38e113a28aSBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
39acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes, flg, 2);
40e113a28aSBarry Smith   snes->errorifnotconverged = flg;
413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
42e113a28aSBarry Smith }
43e113a28aSBarry Smith 
44e113a28aSBarry Smith /*@
45f6dfbefdSBarry Smith    SNESGetErrorIfNotConverged - Indicates if `SNESSolve()` will generate an error if the solver does not converge?
46e113a28aSBarry Smith 
47e113a28aSBarry Smith    Not Collective
48e113a28aSBarry Smith 
49e113a28aSBarry Smith    Input Parameter:
50f6dfbefdSBarry Smith .  snes - iterative context obtained from `SNESCreate()`
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Output Parameter:
53f6dfbefdSBarry Smith .  flag - `PETSC_TRUE` if it will generate an error, else `PETSC_FALSE`
54e113a28aSBarry Smith 
55e113a28aSBarry Smith    Level: intermediate
56e113a28aSBarry Smith 
57f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
58e113a28aSBarry Smith @*/
59d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetErrorIfNotConverged(SNES snes, PetscBool *flag)
60d71ae5a4SJacob Faibussowitsch {
61e113a28aSBarry Smith   PetscFunctionBegin;
62e113a28aSBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
63534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag, 2);
64e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66e113a28aSBarry Smith }
67e113a28aSBarry Smith 
684fc747eaSLawrence Mitchell /*@
69f6dfbefdSBarry Smith     SNESSetAlwaysComputesFinalResidual - tells the `SNES` to always compute the residual at the final solution
704fc747eaSLawrence Mitchell 
71c3339decSBarry Smith    Logically Collective
724fc747eaSLawrence Mitchell 
734fc747eaSLawrence Mitchell     Input Parameters:
74f6dfbefdSBarry Smith +   snes - the shell `SNES`
75f6dfbefdSBarry Smith -   flg - `PETSC_TRUE` to always compute the residual
764fc747eaSLawrence Mitchell 
774fc747eaSLawrence Mitchell    Level: advanced
784fc747eaSLawrence Mitchell 
79f6dfbefdSBarry Smith    Note:
80f6dfbefdSBarry Smith    Some solvers (such as smoothers in a `SNESFAS`) do not need the residual computed at the final solution so skip computing it
81f6dfbefdSBarry Smith    to save time.
82f6dfbefdSBarry Smith 
83f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetAlwaysComputesFinalResidual()`
844fc747eaSLawrence Mitchell @*/
85d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
86d71ae5a4SJacob Faibussowitsch {
874fc747eaSLawrence Mitchell   PetscFunctionBegin;
884fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
894fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = flg;
903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
914fc747eaSLawrence Mitchell }
924fc747eaSLawrence Mitchell 
934fc747eaSLawrence Mitchell /*@
94f6dfbefdSBarry Smith     SNESGetAlwaysComputesFinalResidual - checks if the `SNES` always computes the residual at the final solution
954fc747eaSLawrence Mitchell 
96c3339decSBarry Smith    Logically Collective
974fc747eaSLawrence Mitchell 
984fc747eaSLawrence Mitchell     Input Parameter:
99f6dfbefdSBarry Smith .   snes - the `SNES` context
1004fc747eaSLawrence Mitchell 
1014fc747eaSLawrence Mitchell     Output Parameter:
102f6dfbefdSBarry Smith .   flg - `PETSC_TRUE` if the residual is computed
1034fc747eaSLawrence Mitchell 
1044fc747eaSLawrence Mitchell    Level: advanced
1054fc747eaSLawrence Mitchell 
106f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetAlwaysComputesFinalResidual()`
1074fc747eaSLawrence Mitchell @*/
108d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
109d71ae5a4SJacob Faibussowitsch {
1104fc747eaSLawrence Mitchell   PetscFunctionBegin;
1114fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1124fc747eaSLawrence Mitchell   *flg = snes->alwayscomputesfinalresidual;
1133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1144fc747eaSLawrence Mitchell }
1154fc747eaSLawrence Mitchell 
116e725d27bSBarry Smith /*@
117f6dfbefdSBarry Smith    SNESSetFunctionDomainError - tells `SNES` that the input vector, a proposed new solution, to your function you provided to `SNESSetFunction()` is not
118f0b84518SBarry Smith      in the functions domain. For example, a step with negative pressure.
1194936397dSBarry Smith 
120c3339decSBarry Smith    Logically Collective
1214936397dSBarry Smith 
1224936397dSBarry Smith    Input Parameters:
123f6dfbefdSBarry Smith .  snes - the `SNES` context
1244936397dSBarry Smith 
12528529972SSatish Balay    Level: advanced
1264936397dSBarry Smith 
127f0b84518SBarry Smith    Note:
128f0b84518SBarry Smith    You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or
129f0b84518SBarry Smith    `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
130f0b84518SBarry Smith 
131f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`,
132f0b84518SBarry Smith           `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
1334936397dSBarry Smith @*/
134d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionDomainError(SNES snes)
135d71ae5a4SJacob Faibussowitsch {
1364936397dSBarry Smith   PetscFunctionBegin;
1370700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1385f80ce2aSJacob Faibussowitsch   PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates input vector is not in the function domain");
1394936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1414936397dSBarry Smith }
1424936397dSBarry Smith 
1436a388c36SPeter Brune /*@
144f6dfbefdSBarry Smith    SNESSetJacobianDomainError - tells `SNES` that the function you provided to `SNESSetJacobian()` at the proposed step. For example there is a negative element transformation.
14507b62357SFande Kong 
146c3339decSBarry Smith    Logically Collective
14707b62357SFande Kong 
14807b62357SFande Kong    Input Parameters:
149f6dfbefdSBarry Smith .  snes - the `SNES` context
15007b62357SFande Kong 
15107b62357SFande Kong    Level: advanced
15207b62357SFande Kong 
153f0b84518SBarry Smith    Note:
154f0b84518SBarry Smith    You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or
155f0b84518SBarry Smith    `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
156f0b84518SBarry Smith 
157f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`,
158f0b84518SBarry Smith           `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`
15907b62357SFande Kong @*/
160d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobianDomainError(SNES snes)
161d71ae5a4SJacob Faibussowitsch {
16207b62357SFande Kong   PetscFunctionBegin;
16307b62357SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1645f80ce2aSJacob Faibussowitsch   PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense");
16507b62357SFande Kong   snes->jacobiandomainerror = PETSC_TRUE;
1663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16707b62357SFande Kong }
16807b62357SFande Kong 
16907b62357SFande Kong /*@
170f6dfbefdSBarry Smith    SNESSetCheckJacobianDomainError - tells `SNESSolve()` whether to check if the user called `SNESSetJacobianDomainError()` Jacobian domain error after
171f6dfbefdSBarry Smith    each Jacobian evaluation. By default, we check Jacobian domain error in the debug mode, and do not check it in the optimized mode.
172b351a90bSFande Kong 
173c3339decSBarry Smith    Logically Collective
174b351a90bSFande Kong 
175b351a90bSFande Kong    Input Parameters:
176a2b725a8SWilliam Gropp +  snes - the SNES context
177f6dfbefdSBarry Smith -  flg  - indicates if or not to check Jacobian domain error after each Jacobian evaluation
178b351a90bSFande Kong 
179b351a90bSFande Kong    Level: advanced
180b351a90bSFande Kong 
181f6dfbefdSBarry Smith    Note:
182f6dfbefdSBarry Smith    Checks require one extra parallel synchronization for each Jacobian evaluation
183f6dfbefdSBarry Smith 
184db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()`
185b351a90bSFande Kong @*/
186d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg)
187d71ae5a4SJacob Faibussowitsch {
188b351a90bSFande Kong   PetscFunctionBegin;
189b351a90bSFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
190b351a90bSFande Kong   snes->checkjacdomainerror = flg;
1913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
192b351a90bSFande Kong }
193b351a90bSFande Kong 
194b351a90bSFande Kong /*@
1958383d7d7SFande Kong    SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation.
1968383d7d7SFande Kong 
197c3339decSBarry Smith    Logically Collective
1988383d7d7SFande Kong 
1998383d7d7SFande Kong    Input Parameters:
200f6dfbefdSBarry Smith .  snes - the `SNES` context
2018383d7d7SFande Kong 
2028383d7d7SFande Kong    Output Parameters:
203f6dfbefdSBarry Smith .  flg  - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation
2048383d7d7SFande Kong 
2058383d7d7SFande Kong    Level: advanced
2068383d7d7SFande Kong 
207db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()`
2088383d7d7SFande Kong @*/
209d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg)
210d71ae5a4SJacob Faibussowitsch {
2118383d7d7SFande Kong   PetscFunctionBegin;
2128383d7d7SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
213534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg, 2);
2148383d7d7SFande Kong   *flg = snes->checkjacdomainerror;
2153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2168383d7d7SFande Kong }
2178383d7d7SFande Kong 
2188383d7d7SFande Kong /*@
219f6dfbefdSBarry Smith    SNESGetFunctionDomainError - Gets the status of the domain error after a call to `SNESComputeFunction()`;
2206a388c36SPeter Brune 
221f6dfbefdSBarry Smith    Logically Collective
2226a388c36SPeter Brune 
2236a388c36SPeter Brune    Input Parameters:
224f6dfbefdSBarry Smith .  snes - the `SNES` context
2256a388c36SPeter Brune 
2266a388c36SPeter Brune    Output Parameters:
227f6dfbefdSBarry Smith .  domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise.
2286a388c36SPeter Brune 
229f6dfbefdSBarry Smith    Level: developer
2306a388c36SPeter Brune 
231db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`
2326a388c36SPeter Brune @*/
233d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
234d71ae5a4SJacob Faibussowitsch {
2356a388c36SPeter Brune   PetscFunctionBegin;
2366a388c36SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
237534a8f05SLisandro Dalcin   PetscValidBoolPointer(domainerror, 2);
2386a388c36SPeter Brune   *domainerror = snes->domainerror;
2393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2406a388c36SPeter Brune }
2416a388c36SPeter Brune 
24207b62357SFande Kong /*@
243f6dfbefdSBarry Smith    SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to `SNESComputeJacobian()`;
24407b62357SFande Kong 
245c3339decSBarry Smith    Logically Collective
24607b62357SFande Kong 
24707b62357SFande Kong    Input Parameters:
248f6dfbefdSBarry Smith .  snes - the `SNES` context
24907b62357SFande Kong 
25007b62357SFande Kong    Output Parameters:
251f6dfbefdSBarry Smith .  domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise.
25207b62357SFande Kong 
25307b62357SFande Kong    Level: advanced
25407b62357SFande Kong 
255c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()`
25607b62357SFande Kong @*/
257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror)
258d71ae5a4SJacob Faibussowitsch {
25907b62357SFande Kong   PetscFunctionBegin;
26007b62357SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
261534a8f05SLisandro Dalcin   PetscValidBoolPointer(domainerror, 2);
26207b62357SFande Kong   *domainerror = snes->jacobiandomainerror;
2633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26407b62357SFande Kong }
26507b62357SFande Kong 
26655849f57SBarry Smith /*@C
267f6dfbefdSBarry Smith   SNESLoad - Loads a `SNES` that has been stored in `PETSCVIEWERBINARY` with `SNESView()`.
26855849f57SBarry Smith 
269c3339decSBarry Smith   Collective
27055849f57SBarry Smith 
27155849f57SBarry Smith   Input Parameters:
272f6dfbefdSBarry Smith + newdm - the newly loaded `SNES`, this needs to have been created with `SNESCreate()` or
273f6dfbefdSBarry Smith            some related function before a call to `SNESLoad()`.
274f6dfbefdSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()`
27555849f57SBarry Smith 
27655849f57SBarry Smith    Level: intermediate
27755849f57SBarry Smith 
278f6dfbefdSBarry Smith   Note:
279f6dfbefdSBarry Smith    The type is determined by the data in the file, any type set into the `SNES` before this call is ignored.
28055849f57SBarry Smith 
281f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNESType`, `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()`
28255849f57SBarry Smith @*/
283d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer)
284d71ae5a4SJacob Faibussowitsch {
28555849f57SBarry Smith   PetscBool isbinary;
286060da220SMatthew G. Knepley   PetscInt  classid;
28755849f57SBarry Smith   char      type[256];
28855849f57SBarry Smith   KSP       ksp;
2892d53ad75SBarry Smith   DM        dm;
2902d53ad75SBarry Smith   DMSNES    dmsnes;
29155849f57SBarry Smith 
29255849f57SBarry Smith   PetscFunctionBegin;
2932d53ad75SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
29455849f57SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
2959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
2965f80ce2aSJacob Faibussowitsch   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
29755849f57SBarry Smith 
2989566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT));
2995f80ce2aSJacob Faibussowitsch   PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file");
3009566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
3019566063dSJacob Faibussowitsch   PetscCall(SNESSetType(snes, type));
302dbbe0bcdSBarry Smith   PetscTryTypeMethod(snes, load, viewer);
3039566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
3049566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &dmsnes));
3059566063dSJacob Faibussowitsch   PetscCall(DMSNESLoad(dmsnes, viewer));
3069566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
3079566063dSJacob Faibussowitsch   PetscCall(KSPLoad(ksp, viewer));
3083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30955849f57SBarry Smith }
3106a388c36SPeter Brune 
3119804daf3SBarry Smith #include <petscdraw.h>
312e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
313e04113cfSBarry Smith   #include <petscviewersaws.h>
314bfb97211SBarry Smith #endif
3158404b7f3SBarry Smith 
316fe2efc57SMark /*@C
317f6dfbefdSBarry Smith    SNESViewFromOptions - View a `SNES` based on the options database
318fe2efc57SMark 
319c3339decSBarry Smith    Collective
320fe2efc57SMark 
321fe2efc57SMark    Input Parameters:
322f6dfbefdSBarry Smith +  A - the `SNES` context
323736c3998SJose E. Roman .  obj - Optional object
324736c3998SJose E. Roman -  name - command line option
325fe2efc57SMark 
326fe2efc57SMark    Level: intermediate
327f6dfbefdSBarry Smith 
328db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()`
329fe2efc57SMark @*/
330d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[])
331d71ae5a4SJacob Faibussowitsch {
332fe2efc57SMark   PetscFunctionBegin;
333fe2efc57SMark   PetscValidHeaderSpecific(A, SNES_CLASSID, 1);
3349566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
3353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
336fe2efc57SMark }
337fe2efc57SMark 
338789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *);
339789d8953SBarry Smith 
3407e2c5f70SBarry Smith /*@C
341f6dfbefdSBarry Smith    SNESView - Prints the `SNES` data structure.
3429b94acceSBarry Smith 
343c3339decSBarry Smith    Collective
344fee21e36SBarry Smith 
345c7afd0dbSLois Curfman McInnes    Input Parameters:
346f6dfbefdSBarry Smith +  snes - the `SNES` context
347f6dfbefdSBarry Smith -  viewer - the `PetscViewer`
348c7afd0dbSLois Curfman McInnes 
3499b94acceSBarry Smith    Options Database Key:
350f6dfbefdSBarry Smith .  -snes_view - Calls `SNESView()` at end of `SNESSolve()`
3519b94acceSBarry Smith 
3529b94acceSBarry Smith    Notes:
3539b94acceSBarry Smith    The available visualization contexts include
354f6dfbefdSBarry Smith +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
355f6dfbefdSBarry Smith -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
356c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
357c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
358c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
3599b94acceSBarry Smith 
360052bf0daSPierre Jolivet    The available formats include
361f6dfbefdSBarry Smith +     `PETSC_VIEWER_DEFAULT` - standard output (default)
362f6dfbefdSBarry Smith -     `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `SNESNASM`
363052bf0daSPierre Jolivet 
3643e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
365f6dfbefdSBarry Smith    `PetscViewerASCIIOpen()` - output to a specified file.
3669b94acceSBarry Smith 
367f6dfbefdSBarry Smith   In the debugger you can do "call `SNESView`(snes,0)" to display the `SNES` solver. (The same holds for any PETSc object viewer).
368595c91d4SBarry Smith 
36936851e7fSLois Curfman McInnes    Level: beginner
37036851e7fSLois Curfman McInnes 
371f6dfbefdSBarry Smith .seealso: `SNES`, `SNESLoad()`, `SNESCreate()`, `PetscViewerASCIIOpen()`
3729b94acceSBarry Smith @*/
373d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView(SNES snes, PetscViewer viewer)
374d71ae5a4SJacob Faibussowitsch {
375fa9f3622SBarry Smith   SNESKSPEW     *kctx;
37694b7f48cSBarry Smith   KSP            ksp;
3777f1410a3SPeter Brune   SNESLineSearch linesearch;
37872a02f06SBarry Smith   PetscBool      iascii, isstring, isbinary, isdraw;
3792d53ad75SBarry Smith   DMSNES         dmsnes;
380e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
381536b137fSBarry Smith   PetscBool issaws;
382bfb97211SBarry Smith #endif
3839b94acceSBarry Smith 
3843a40ed3dSBarry Smith   PetscFunctionBegin;
3850700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
38648a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer));
3870700a824SBarry Smith   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
388c9780b6fSBarry Smith   PetscCheckSameComm(snes, 1, viewer, 2);
38974679c65SBarry Smith 
3909566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
3919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
3929566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
3939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
394e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
3959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
396bfb97211SBarry Smith #endif
39732077d6dSBarry Smith   if (iascii) {
398dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
3998404b7f3SBarry Smith     DM               dm;
4008404b7f3SBarry Smith     PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *);
4018404b7f3SBarry Smith     void       *ctx;
402789d8953SBarry Smith     const char *pre = "";
403dc0571f2SMatthew G. Knepley 
4049566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer));
40548a46eb9SPierre Jolivet     if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, "  SNES has not been set up so information may be incomplete\n"));
406e7788613SBarry Smith     if (snes->ops->view) {
4079566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
408dbbe0bcdSBarry Smith       PetscUseTypeMethod(snes, view, viewer);
4099566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
4100ef38995SBarry Smith     }
41163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs));
4129566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol));
41348a46eb9SPierre Jolivet     if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its));
41463a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs));
4159566063dSJacob Faibussowitsch     PetscCall(SNESGetNormSchedule(snes, &normschedule));
4169566063dSJacob Faibussowitsch     if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, "  norm schedule %s\n", SNESNormSchedules[normschedule]));
41748a46eb9SPierre Jolivet     if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, "  total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence));
4189b94acceSBarry Smith     if (snes->ksp_ewconv) {
419fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
4209b94acceSBarry Smith       if (kctx) {
42163a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version));
4229566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "    rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold));
4239566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "    gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2));
4249b94acceSBarry Smith       }
4259b94acceSBarry Smith     }
426eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
4279566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Preconditioned is never rebuilt\n"));
428eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
42963a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner));
430eb1f6c34SBarry Smith     }
431eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
4329566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Jacobian is never rebuilt\n"));
433eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
43463a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian));
435eb1f6c34SBarry Smith     }
4369566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
4379566063dSJacob Faibussowitsch     PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx));
438789d8953SBarry Smith     if (snes->mf_operator) {
4399566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Jacobian is applied matrix-free with differencing\n"));
440789d8953SBarry Smith       pre = "Preconditioning ";
441789d8953SBarry Smith     }
4428404b7f3SBarry Smith     if (cJ == SNESComputeJacobianDefault) {
4439566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  %sJacobian is built using finite differences one column at a time\n", pre));
4448404b7f3SBarry Smith     } else if (cJ == SNESComputeJacobianDefaultColor) {
4459566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  %sJacobian is built using finite differences with coloring\n", pre));
446789d8953SBarry Smith       /* it slightly breaks data encapsulation for access the DMDA information directly */
447789d8953SBarry Smith     } else if (cJ == SNESComputeJacobian_DMDA) {
448789d8953SBarry Smith       MatFDColoring fdcoloring;
4499566063dSJacob Faibussowitsch       PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring));
450789d8953SBarry Smith       if (fdcoloring) {
4519566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  %sJacobian is built using colored finite differences on a DMDA\n", pre));
452789d8953SBarry Smith       } else {
4539566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "  %sJacobian is built using a DMDA local Jacobian\n", pre));
454789d8953SBarry Smith       }
455789d8953SBarry Smith     } else if (snes->mf) {
4569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Jacobian is applied matrix-free with differencing, no explicit Jacobian\n"));
4578404b7f3SBarry Smith     }
4580f5bd95cSBarry Smith   } else if (isstring) {
459317d6ea6SBarry Smith     const char *type;
4609566063dSJacob Faibussowitsch     PetscCall(SNESGetType(snes, &type));
4619566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type));
462dbbe0bcdSBarry Smith     PetscTryTypeMethod(snes, view, viewer);
46355849f57SBarry Smith   } else if (isbinary) {
46455849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
46555849f57SBarry Smith     MPI_Comm    comm;
46655849f57SBarry Smith     PetscMPIInt rank;
46755849f57SBarry Smith     char        type[256];
46855849f57SBarry Smith 
4699566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)snes, &comm));
4709566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm, &rank));
471dd400576SPatrick Sanan     if (rank == 0) {
4729566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
4739566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type)));
4749566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR));
47555849f57SBarry Smith     }
476dbbe0bcdSBarry Smith     PetscTryTypeMethod(snes, view, viewer);
47772a02f06SBarry Smith   } else if (isdraw) {
47872a02f06SBarry Smith     PetscDraw draw;
47972a02f06SBarry Smith     char      str[36];
48089fd9fafSBarry Smith     PetscReal x, y, bottom, h;
48172a02f06SBarry Smith 
4829566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
4839566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y));
4849566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str)));
4859566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str)));
4869566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h));
48789fd9fafSBarry Smith     bottom = y - h;
4889566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom));
489dbbe0bcdSBarry Smith     PetscTryTypeMethod(snes, view, viewer);
490e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
491536b137fSBarry Smith   } else if (issaws) {
492d45a07a7SBarry Smith     PetscMPIInt rank;
4932657e9d9SBarry Smith     const char *name;
494d45a07a7SBarry Smith 
4959566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)snes, &name));
4969566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
497dd400576SPatrick Sanan     if (!((PetscObject)snes)->amsmem && rank == 0) {
498d45a07a7SBarry Smith       char dir[1024];
499d45a07a7SBarry Smith 
5009566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer));
5019566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name));
502792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT));
50348a46eb9SPierre Jolivet       if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE));
5049566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name));
505792fecdfSBarry Smith       PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE));
506f05ece33SBarry Smith     }
507bfb97211SBarry Smith #endif
50872a02f06SBarry Smith   }
50972a02f06SBarry Smith   if (snes->linesearch) {
5109566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &linesearch));
5119566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5129566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchView(linesearch, viewer));
5139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
51419bcc07fSBarry Smith   }
515efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
5169566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5179566063dSJacob Faibussowitsch     PetscCall(SNESView(snes->npc, viewer));
5189566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
5194a0c5b0cSMatthew G Knepley   }
5209566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
5219566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(snes->dm, &dmsnes));
5229566063dSJacob Faibussowitsch   PetscCall(DMSNESView(dmsnes, viewer));
5239566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
5242c155ee1SBarry Smith   if (snes->usesksp) {
5259566063dSJacob Faibussowitsch     PetscCall(SNESGetKSP(snes, &ksp));
5269566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5279566063dSJacob Faibussowitsch     PetscCall(KSPView(ksp, viewer));
5289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
5292c155ee1SBarry Smith   }
53072a02f06SBarry Smith   if (isdraw) {
53172a02f06SBarry Smith     PetscDraw draw;
5329566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
5339566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
5347f1410a3SPeter Brune   }
5353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5369b94acceSBarry Smith }
5379b94acceSBarry Smith 
53876b2cf59SMatthew Knepley /*
53976b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
54076b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
54176b2cf59SMatthew Knepley */
54276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
543a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
5446849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
54576b2cf59SMatthew Knepley 
546ac226902SBarry Smith /*@C
547f6dfbefdSBarry Smith   SNESAddOptionsChecker - Adds an additional function to check for `SNES` options.
54876b2cf59SMatthew Knepley 
54976b2cf59SMatthew Knepley   Not Collective
55076b2cf59SMatthew Knepley 
55176b2cf59SMatthew Knepley   Input Parameter:
55276b2cf59SMatthew Knepley . snescheck - function that checks for options
55376b2cf59SMatthew Knepley 
55476b2cf59SMatthew Knepley   Level: developer
55576b2cf59SMatthew Knepley 
556f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`
55776b2cf59SMatthew Knepley @*/
558d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
559d71ae5a4SJacob Faibussowitsch {
56076b2cf59SMatthew Knepley   PetscFunctionBegin;
56163a3b9bcSJacob Faibussowitsch   PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS);
56276b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
5633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
56476b2cf59SMatthew Knepley }
56576b2cf59SMatthew Knepley 
566d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
567d71ae5a4SJacob Faibussowitsch {
568aa3661deSLisandro Dalcin   Mat          J;
569895c21f2SBarry Smith   MatNullSpace nullsp;
570aa3661deSLisandro Dalcin 
571aa3661deSLisandro Dalcin   PetscFunctionBegin;
5720700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
573aa3661deSLisandro Dalcin 
57498613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
57598613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
5769566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func));
57798613b67SLisandro Dalcin   }
57898613b67SLisandro Dalcin 
5790fdf79fbSJacob Faibussowitsch   PetscCheck(version == 1 || version == 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2");
580aa3661deSLisandro Dalcin   if (version == 1) {
5819566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes, &J));
5829566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix));
5839566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
5841e2ae407SBarry Smith     /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */
5850fdf79fbSJacob Faibussowitsch   } else /* if (version == 2) */ {
5865f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first");
587570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
588f6dfbefdSBarry Smith     PetscCall(MatCreateSNESMFMore(snes, snes->vec_func, &J));
589aa3661deSLisandro Dalcin #else
5902479783cSJose E. Roman     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)");
591aa3661deSLisandro Dalcin #endif
5920fdf79fbSJacob Faibussowitsch   }
593aa3661deSLisandro Dalcin 
594895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
595895c21f2SBarry Smith   if (snes->jacobian) {
5969566063dSJacob Faibussowitsch     PetscCall(MatGetNullSpace(snes->jacobian, &nullsp));
5971baa6e33SBarry Smith     if (nullsp) PetscCall(MatSetNullSpace(J, nullsp));
598895c21f2SBarry Smith   }
599895c21f2SBarry Smith 
60063a3b9bcSJacob Faibussowitsch   PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version));
601d3462f78SMatthew Knepley   if (hasOperator) {
602aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
603aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
6049566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL));
605aa3661deSLisandro Dalcin   } else {
606aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
6073232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
608b552625fSStefano Zampini     if (snes->npcside == PC_LEFT && snes->npc) {
6099566063dSJacob Faibussowitsch       if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL));
610172a4300SPeter Brune     } else {
611789d8953SBarry Smith       KSP       ksp;
612789d8953SBarry Smith       PC        pc;
613789d8953SBarry Smith       PetscBool match;
614789d8953SBarry Smith 
6159566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL));
616aa3661deSLisandro Dalcin       /* Force no preconditioner */
6179566063dSJacob Faibussowitsch       PetscCall(SNESGetKSP(snes, &ksp));
6189566063dSJacob Faibussowitsch       PetscCall(KSPGetPC(ksp, &pc));
6192698c518SLisandro Dalcin       PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, ""));
620aa3661deSLisandro Dalcin       if (!match) {
6219566063dSJacob Faibussowitsch         PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n"));
6229566063dSJacob Faibussowitsch         PetscCall(PCSetType(pc, PCNONE));
623aa3661deSLisandro Dalcin       }
624aa3661deSLisandro Dalcin     }
625789d8953SBarry Smith   }
6269566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&J));
6273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
628aa3661deSLisandro Dalcin }
629aa3661deSLisandro Dalcin 
630d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx)
631d71ae5a4SJacob Faibussowitsch {
632dfe15315SJed Brown   SNES snes = (SNES)ctx;
6330298fd71SBarry Smith   Vec  Xfine, Xfine_named = NULL, Xcoarse;
634dfe15315SJed Brown 
635dfe15315SJed Brown   PetscFunctionBegin;
63616ebb321SJed Brown   if (PetscLogPrintInfo) {
63716ebb321SJed Brown     PetscInt finelevel, coarselevel, fineclevel, coarseclevel;
6389566063dSJacob Faibussowitsch     PetscCall(DMGetRefineLevel(dmfine, &finelevel));
6399566063dSJacob Faibussowitsch     PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel));
6409566063dSJacob Faibussowitsch     PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel));
6419566063dSJacob Faibussowitsch     PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel));
64263a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(dmfine, "Restricting SNES solution vector from level %" PetscInt_FMT "-%" PetscInt_FMT " to level %" PetscInt_FMT "-%" PetscInt_FMT "\n", finelevel, fineclevel, coarselevel, coarseclevel));
64316ebb321SJed Brown   }
644dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
645dfe15315SJed Brown   else {
6469566063dSJacob Faibussowitsch     PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named));
647dfe15315SJed Brown     Xfine = Xfine_named;
648dfe15315SJed Brown   }
6499566063dSJacob Faibussowitsch   PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse));
650907f5c5aSLawrence Mitchell   if (Inject) {
6519566063dSJacob Faibussowitsch     PetscCall(MatRestrict(Inject, Xfine, Xcoarse));
652907f5c5aSLawrence Mitchell   } else {
6539566063dSJacob Faibussowitsch     PetscCall(MatRestrict(Restrict, Xfine, Xcoarse));
6549566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale));
655907f5c5aSLawrence Mitchell   }
6569566063dSJacob Faibussowitsch   PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse));
6579566063dSJacob Faibussowitsch   if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named));
6583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
659dfe15315SJed Brown }
660dfe15315SJed Brown 
661d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx)
662d71ae5a4SJacob Faibussowitsch {
66316ebb321SJed Brown   PetscFunctionBegin;
6649566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx));
6653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
66616ebb321SJed Brown }
66716ebb321SJed Brown 
668a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
669a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
670d71ae5a4SJacob Faibussowitsch static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx)
671d71ae5a4SJacob Faibussowitsch {
672caa4e7f2SJed Brown   SNES  snes = (SNES)ctx;
6730298fd71SBarry Smith   Vec   X, Xnamed = NULL;
674dfe15315SJed Brown   DM    dmsave;
6754e269d77SPeter Brune   void *ctxsave;
67625ce1634SJed Brown   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL;
677caa4e7f2SJed Brown 
678caa4e7f2SJed Brown   PetscFunctionBegin;
679dfe15315SJed Brown   dmsave = snes->dm;
6809566063dSJacob Faibussowitsch   PetscCall(KSPGetDM(ksp, &snes->dm));
681dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
6829371c9d4SSatish Balay   else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed));
683dfe15315SJed Brown     X = Xnamed;
6849566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave));
6854e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
68648a46eb9SPierre Jolivet     if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL));
6874e269d77SPeter Brune   }
6884dde8bb0SMatthew G. Knepley   /* Make sure KSP DM has the Jacobian computation routine */
6894dde8bb0SMatthew G. Knepley   {
6904dde8bb0SMatthew G. Knepley     DMSNES sdm;
6914e269d77SPeter Brune 
6929566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNES(snes->dm, &sdm));
69348a46eb9SPierre Jolivet     if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm));
6944dde8bb0SMatthew G. Knepley   }
6952b93b426SMatthew G. Knepley   /* Compute the operators */
6969566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes, X, A, B));
6972b93b426SMatthew G. Knepley   /* Put the previous context back */
69848a46eb9SPierre Jolivet   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave));
6994e269d77SPeter Brune 
7009566063dSJacob Faibussowitsch   if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed));
701dfe15315SJed Brown   snes->dm = dmsave;
7023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
703caa4e7f2SJed Brown }
704caa4e7f2SJed Brown 
7056cab3a1bSJed Brown /*@
706f6dfbefdSBarry Smith    SNESSetUpMatrices - ensures that matrices are available for `SNES`, this is called by `SNESSetUp_XXX()`
7076cab3a1bSJed Brown 
7086cab3a1bSJed Brown    Collective
7096cab3a1bSJed Brown 
7104165533cSJose E. Roman    Input Parameter:
7116cab3a1bSJed Brown .  snes - snes to configure
7126cab3a1bSJed Brown 
7136cab3a1bSJed Brown    Level: developer
7146cab3a1bSJed Brown 
715f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUp()`
7166cab3a1bSJed Brown @*/
717d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpMatrices(SNES snes)
718d71ae5a4SJacob Faibussowitsch {
7196cab3a1bSJed Brown   DM     dm;
720942e3340SBarry Smith   DMSNES sdm;
7216cab3a1bSJed Brown 
7226cab3a1bSJed Brown   PetscFunctionBegin;
7239566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
7249566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
72558b371f3SBarry Smith   if (!snes->jacobian && snes->mf) {
7266cab3a1bSJed Brown     Mat   J;
7276cab3a1bSJed Brown     void *functx;
7289566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes, &J));
7299566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix));
7309566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
7319566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes, NULL, NULL, &functx));
7329566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL));
7339566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
734caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
7356cab3a1bSJed Brown     Mat J, B;
7369566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes, &J));
7379566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix));
7389566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
7399566063dSJacob Faibussowitsch     PetscCall(DMCreateMatrix(snes->dm, &B));
74006f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
7419566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL));
7429566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
7439566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
744caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
7451ba9b98eSMatthew G. Knepley     PetscDS   prob;
7466cab3a1bSJed Brown     Mat       J, B;
7471ba9b98eSMatthew G. Knepley     PetscBool hasPrec = PETSC_FALSE;
7481ba9b98eSMatthew G. Knepley 
7496cab3a1bSJed Brown     J = snes->jacobian;
7509566063dSJacob Faibussowitsch     PetscCall(DMGetDS(dm, &prob));
7519566063dSJacob Faibussowitsch     if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec));
7529566063dSJacob Faibussowitsch     if (J) PetscCall(PetscObjectReference((PetscObject)J));
7539566063dSJacob Faibussowitsch     else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J));
7549566063dSJacob Faibussowitsch     PetscCall(DMCreateMatrix(snes->dm, &B));
7559566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL));
7569566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
7579566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
7586cab3a1bSJed Brown   }
759caa4e7f2SJed Brown   {
760caa4e7f2SJed Brown     KSP ksp;
7619566063dSJacob Faibussowitsch     PetscCall(SNESGetKSP(snes, &ksp));
7629566063dSJacob Faibussowitsch     PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes));
7639566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes));
764caa4e7f2SJed Brown   }
7653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7666cab3a1bSJed Brown }
7676cab3a1bSJed Brown 
768d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes)
769d71ae5a4SJacob Faibussowitsch {
7705e7c47f3SMatthew G. Knepley   PetscInt i;
7715e7c47f3SMatthew G. Knepley 
7725e7c47f3SMatthew G. Knepley   PetscFunctionBegin;
7733ba16761SJacob Faibussowitsch   if (!snes->pauseFinal) PetscFunctionReturn(PETSC_SUCCESS);
7745e7c47f3SMatthew G. Knepley   for (i = 0; i < snes->numbermonitors; ++i) {
7755e7c47f3SMatthew G. Knepley     PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i];
7765e7c47f3SMatthew G. Knepley     PetscDraw             draw;
7775e7c47f3SMatthew G. Knepley     PetscReal             lpause;
7785e7c47f3SMatthew G. Knepley 
7795e7c47f3SMatthew G. Knepley     if (!vf) continue;
7805e7c47f3SMatthew G. Knepley     if (vf->lg) {
7815e7c47f3SMatthew G. Knepley       if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue;
7825e7c47f3SMatthew G. Knepley       if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue;
7839566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGGetDraw(vf->lg, &draw));
7849566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(draw, &lpause));
7859566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, -1.0));
7869566063dSJacob Faibussowitsch       PetscCall(PetscDrawPause(draw));
7879566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, lpause));
7885e7c47f3SMatthew G. Knepley     } else {
7895e7c47f3SMatthew G. Knepley       PetscBool isdraw;
7905e7c47f3SMatthew G. Knepley 
7915e7c47f3SMatthew G. Knepley       if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue;
7925e7c47f3SMatthew G. Knepley       if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue;
7939566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw));
7945e7c47f3SMatthew G. Knepley       if (!isdraw) continue;
7959566063dSJacob Faibussowitsch       PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw));
7969566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(draw, &lpause));
7979566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, -1.0));
7989566063dSJacob Faibussowitsch       PetscCall(PetscDrawPause(draw));
7999566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, lpause));
8005e7c47f3SMatthew G. Knepley     }
8015e7c47f3SMatthew G. Knepley   }
8023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8035e7c47f3SMatthew G. Knepley }
8045e7c47f3SMatthew G. Knepley 
805fde5950dSBarry Smith /*@C
806fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
807fde5950dSBarry Smith 
808c3339decSBarry Smith    Collective
809fde5950dSBarry Smith 
810fde5950dSBarry Smith    Input Parameters:
811fde5950dSBarry Smith +  snes - SNES object you wish to monitor
812fde5950dSBarry Smith .  name - the monitor type one is seeking
813fde5950dSBarry Smith .  help - message indicating what monitoring is done
814fde5950dSBarry Smith .  manual - manual page for the monitor
815fde5950dSBarry Smith .  monitor - the monitor function
816f6dfbefdSBarry 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
817fde5950dSBarry Smith 
818f6dfbefdSBarry Smith    Options Database Key:
819f6dfbefdSBarry Smith .  -name - trigger the use of this monitor in `SNESSetFromOptions()`
820f6dfbefdSBarry Smith 
821f6dfbefdSBarry Smith    Level: advanced
822fde5950dSBarry Smith 
823db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
824db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
825db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
826db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
827c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
828db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
829db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
830fde5950dSBarry Smith @*/
831d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSetFromOptions(SNES snes, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNES, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNES, PetscViewerAndFormat *))
832d71ae5a4SJacob Faibussowitsch {
833fde5950dSBarry Smith   PetscViewer       viewer;
834fde5950dSBarry Smith   PetscViewerFormat format;
835fde5950dSBarry Smith   PetscBool         flg;
836fde5950dSBarry Smith 
837fde5950dSBarry Smith   PetscFunctionBegin;
8389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, name, &viewer, &format, &flg));
839fde5950dSBarry Smith   if (flg) {
840d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
8419566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf));
8429566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
8431baa6e33SBarry Smith     if (monitorsetup) PetscCall((*monitorsetup)(snes, vf));
8449566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy));
845fde5950dSBarry Smith   }
8463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
847fde5950dSBarry Smith }
848fde5950dSBarry Smith 
849d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, MPI_Comm comm, const char *prefix)
850d71ae5a4SJacob Faibussowitsch {
8510f0abf79SStefano Zampini   PetscFunctionBegin;
8520f0abf79SStefano Zampini   PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP");
8530f0abf79SStefano Zampini   PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", NULL, kctx->version, &kctx->version, NULL));
8540f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", NULL, kctx->rtol_0, &kctx->rtol_0, NULL));
8550f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", NULL, kctx->rtol_max, &kctx->rtol_max, NULL));
8560f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", NULL, kctx->gamma, &kctx->gamma, NULL));
8570f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", NULL, kctx->alpha, &kctx->alpha, NULL));
8580f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL));
8590f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", NULL, kctx->threshold, &kctx->threshold, NULL));
8600f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL));
8610f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL));
8620f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL));
8630f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL));
8640f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL));
8650f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL));
8660f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL));
8670f0abf79SStefano Zampini   PetscOptionsEnd();
8683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8690f0abf79SStefano Zampini }
8700f0abf79SStefano Zampini 
8719b94acceSBarry Smith /*@
872f6dfbefdSBarry Smith    SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options.
8739b94acceSBarry Smith 
874c3339decSBarry Smith    Collective
875c7afd0dbSLois Curfman McInnes 
8769b94acceSBarry Smith    Input Parameter:
877f6dfbefdSBarry Smith .  snes - the `SNES` context
8789b94acceSBarry Smith 
87936851e7fSLois Curfman McInnes    Options Database Keys:
880f6dfbefdSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list
88182738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
88282738288SBarry Smith                 of the change in the solution between steps
88370441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
884b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
885e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
886be5caee7SBarry Smith .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
887b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
888b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
8894839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
890ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
891a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
8923d5a8a6aSBarry Smith .  -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve()
893e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
8943d5a8a6aSBarry Smith .  -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve()
895b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
896f362779dSJed Brown .  -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver.
897f6dfbefdSBarry Smith                                default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense
898f6dfbefdSBarry Smith                                of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space.
899fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
900fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
901fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
902fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
9034619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
904459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
9055e7c47f3SMatthew G. Knepley .  -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends
906e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
907e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
9085968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
909b5badacbSBarry Smith .  -snes_converged_reason - print the reason for convergence/divergence after each solve
910e62ac41dSBarry Smith .  -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner
911e62ac41dSBarry 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.
912e62ac41dSBarry 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.
91382738288SBarry Smith 
914f6dfbefdSBarry Smith     Options Database Keys for Eisenstat-Walker method:
915fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
9164b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
91736851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
91836851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
91936851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
92036851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
92136851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
92236851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
92382738288SBarry Smith 
92411ca99fdSLois Curfman McInnes    Notes:
925ec5066bdSBarry Smith    To see all options, run your program with the -help option or consult the users manual
926ec5066bdSBarry Smith 
927f6dfbefdSBarry Smith    `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with
928f6dfbefdSBarry Smith    finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object.
92983e2fdc7SBarry Smith 
93036851e7fSLois Curfman McInnes    Level: beginner
93136851e7fSLois Curfman McInnes 
932f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()`
9339b94acceSBarry Smith @*/
934d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes)
935d71ae5a4SJacob Faibussowitsch {
9368afaa268SBarry Smith   PetscBool   flg, pcset, persist, set;
937d8f46077SPeter Brune   PetscInt    i, indx, lag, grids;
93804d7464bSBarry Smith   const char *deft        = SNESNEWTONLS;
939649ef022SMatthew Knepley   const char *convtests[] = {"default", "skip", "correct_pressure"};
94085385478SLisandro Dalcin   SNESKSPEW  *kctx        = NULL;
9410f0abf79SStefano Zampini   char        type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256];
942c40d0f55SPeter Brune   PCSide      pcside;
943a64e098fSPeter Brune   const char *optionsprefix;
9449b94acceSBarry Smith 
9453a40ed3dSBarry Smith   PetscFunctionBegin;
9460700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
9479566063dSJacob Faibussowitsch   PetscCall(SNESRegisterAll());
948d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)snes);
949639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
9509566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg));
951d64ed03dSBarry Smith   if (flg) {
9529566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes, type));
9537adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
9549566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes, deft));
955d64ed03dSBarry Smith   }
9569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL));
9579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL));
958186905e3SBarry Smith 
9599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL));
9609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL));
9619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL));
9629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL));
9639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL));
9649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL));
9659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL));
9669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL));
9679566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL));
96885385478SLisandro Dalcin 
9699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg));
970a8054027SBarry Smith   if (flg) {
9715f80ce2aSJacob 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");
9729566063dSJacob Faibussowitsch     PetscCall(SNESSetLagPreconditioner(snes, lag));
973a8054027SBarry Smith   }
9749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg));
9751baa6e33SBarry Smith   if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist));
9769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg));
977e35cf81dSBarry Smith   if (flg) {
9785f80ce2aSJacob 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");
9799566063dSJacob Faibussowitsch     PetscCall(SNESSetLagJacobian(snes, lag));
980e35cf81dSBarry Smith   }
9819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg));
9821baa6e33SBarry Smith   if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist));
98337ec4e1aSPeter Brune 
9849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg));
9851baa6e33SBarry Smith   if (flg) PetscCall(SNESSetGridSequence(snes, grids));
986a8054027SBarry Smith 
9879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg));
98885385478SLisandro Dalcin   if (flg) {
98985385478SLisandro Dalcin     switch (indx) {
990d71ae5a4SJacob Faibussowitsch     case 0:
991d71ae5a4SJacob Faibussowitsch       PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL));
992d71ae5a4SJacob Faibussowitsch       break;
993d71ae5a4SJacob Faibussowitsch     case 1:
994d71ae5a4SJacob Faibussowitsch       PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL));
995d71ae5a4SJacob Faibussowitsch       break;
996d71ae5a4SJacob Faibussowitsch     case 2:
997d71ae5a4SJacob Faibussowitsch       PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL));
998d71ae5a4SJacob Faibussowitsch       break;
99985385478SLisandro Dalcin     }
100085385478SLisandro Dalcin   }
100185385478SLisandro Dalcin 
10029566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg));
10039566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx));
1004fdacfa88SPeter Brune 
10059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg));
10069566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx));
1007186905e3SBarry Smith 
100885385478SLisandro Dalcin   kctx = (SNESKSPEW *)snes->kspconvctx;
100985385478SLisandro Dalcin 
10109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL));
1011186905e3SBarry Smith 
10120f0abf79SStefano Zampini   PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
10130f0abf79SStefano Zampini   PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_"));
10140f0abf79SStefano Zampini   PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix));
10150f0abf79SStefano Zampini 
10169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL));
10179566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL));
10189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL));
10199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL));
10209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL));
10219566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL));
10229566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL));
1023186905e3SBarry Smith 
102490d69ab7SBarry Smith   flg = PETSC_FALSE;
10259566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set));
10269566063dSJacob Faibussowitsch   if (set && flg) PetscCall(SNESMonitorCancel(snes));
1027eabae89aSBarry Smith 
10289566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp));
10299566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL));
10309566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL));
1031eabae89aSBarry Smith 
10329566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp));
10339566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL));
10349566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL));
10359566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL));
10369566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL));
10379566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL));
10389566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL));
10399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL));
10402db13446SMatthew G. Knepley 
10419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
10429566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename));
10435180491cSLisandro Dalcin 
104490d69ab7SBarry Smith   flg = PETSC_FALSE;
10459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL));
1046459f5d12SBarry Smith   if (flg) {
1047459f5d12SBarry Smith     PetscViewer ctx;
1048e24b481bSBarry Smith 
10499566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx));
10509566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy));
1051459f5d12SBarry Smith   }
10522e7541e6SPeter Brune 
105390d69ab7SBarry Smith   flg = PETSC_FALSE;
10549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set));
10559566063dSJacob Faibussowitsch   if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes));
1056c4421ceaSFande Kong 
1057c4421ceaSFande Kong   flg = PETSC_FALSE;
10589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL));
10594b27c08aSLois Curfman McInnes   if (flg) {
10606cab3a1bSJed Brown     void *functx;
1061b1f624c7SBarry Smith     DM    dm;
10629566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
1063800f99ffSJeremy L Thompson     PetscCall(DMSNESUnsetJacobianContext_Internal(dm));
10649566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes, NULL, NULL, &functx));
10659566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx));
10669566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n"));
10679b94acceSBarry Smith   }
1068639f9d9dSBarry Smith 
106944848bc4SPeter Brune   flg = PETSC_FALSE;
10709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL));
10711baa6e33SBarry Smith   if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL));
107297584545SPeter Brune 
107397584545SPeter Brune   flg = PETSC_FALSE;
10749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL));
107544848bc4SPeter Brune   if (flg) {
1076c52e227fSPeter Brune     DM dm;
10779566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
1078800f99ffSJeremy L Thompson     PetscCall(DMSNESUnsetJacobianContext_Internal(dm));
10799566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL));
10809566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n"));
108144848bc4SPeter Brune   }
108244848bc4SPeter Brune 
1083aa3661deSLisandro Dalcin   flg = PETSC_FALSE;
10849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg));
1085d8f46077SPeter Brune   if (flg && snes->mf_operator) {
1086a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
1087d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
1088a8248277SBarry Smith   }
1089aa3661deSLisandro Dalcin   flg = PETSC_FALSE;
10909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg));
1091d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
10929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL));
1093d28543b3SPeter Brune 
1094c40d0f55SPeter Brune   flg = PETSC_FALSE;
10959566063dSJacob Faibussowitsch   PetscCall(SNESGetNPCSide(snes, &pcside));
10969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg));
10979566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetNPCSide(snes, pcside));
1098c40d0f55SPeter Brune 
1099e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
11008a70d858SHong Zhang   /*
11018a70d858SHong Zhang     Publish convergence information using SAWs
11028a70d858SHong Zhang   */
11038a70d858SHong Zhang   flg = PETSC_FALSE;
11049566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL));
11058a70d858SHong Zhang   if (flg) {
11068a70d858SHong Zhang     void *ctx;
11079566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSAWsCreate(snes, &ctx));
11089566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy));
11098a70d858SHong Zhang   }
11108a70d858SHong Zhang #endif
11118a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
1112b90c6cbeSBarry Smith   {
1113b90c6cbeSBarry Smith     PetscBool set;
1114b90c6cbeSBarry Smith     flg = PETSC_FALSE;
11159566063dSJacob Faibussowitsch     PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set));
11161baa6e33SBarry Smith     if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg));
1117b90c6cbeSBarry Smith   }
1118b90c6cbeSBarry Smith #endif
1119b90c6cbeSBarry Smith 
112048a46eb9SPierre Jolivet   for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes));
112176b2cf59SMatthew Knepley 
1122dbbe0bcdSBarry Smith   PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject);
11235d973c19SBarry Smith 
11245d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1125dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject));
1126d0609cedSBarry Smith   PetscOptionsEnd();
11274bbc92c1SBarry Smith 
1128d8d34be6SBarry Smith   if (snes->linesearch) {
11299566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
11309566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetFromOptions(snes->linesearch));
1131d8d34be6SBarry Smith   }
11329e764e56SPeter Brune 
11336aa5e7e9SBarry Smith   if (snes->usesksp) {
11349566063dSJacob Faibussowitsch     if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
11359566063dSJacob Faibussowitsch     PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre));
11369566063dSJacob Faibussowitsch     PetscCall(KSPSetFromOptions(snes->ksp));
11376aa5e7e9SBarry Smith   }
11386991f827SBarry Smith 
1139b5badacbSBarry Smith   /* if user has set the SNES NPC type via options database, create it. */
11409566063dSJacob Faibussowitsch   PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
11419566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset));
114248a46eb9SPierre Jolivet   if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc));
11431baa6e33SBarry Smith   if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc));
1144b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled++;
11453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1146b3cd9a81SMatthew G. Knepley }
1147b3cd9a81SMatthew G. Knepley 
1148b3cd9a81SMatthew G. Knepley /*@
1149f6dfbefdSBarry Smith    SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options
1150b3cd9a81SMatthew G. Knepley 
1151c3339decSBarry Smith    Collective
1152b3cd9a81SMatthew G. Knepley 
1153b3cd9a81SMatthew G. Knepley    Input Parameter:
1154f6dfbefdSBarry Smith .  snes - the `SNES` context
1155b3cd9a81SMatthew G. Knepley 
1156b3cd9a81SMatthew G. Knepley    Level: beginner
1157b3cd9a81SMatthew G. Knepley 
1158f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()`
1159b3cd9a81SMatthew G. Knepley @*/
1160d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes)
1161d71ae5a4SJacob Faibussowitsch {
1162b3cd9a81SMatthew G. Knepley   PetscFunctionBegin;
11639566063dSJacob Faibussowitsch   if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes));
11643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
11659b94acceSBarry Smith }
11669b94acceSBarry Smith 
1167bb9467b5SJed Brown /*@C
1168d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1169d25893d9SBarry Smith    the nonlinear solvers.
1170d25893d9SBarry Smith 
1171c3339decSBarry Smith    Logically Collective
1172d25893d9SBarry Smith 
1173d25893d9SBarry Smith    Input Parameters:
1174f6dfbefdSBarry Smith +  snes - the `SNES` context
1175d25893d9SBarry Smith .  compute - function to compute the context
1176d25893d9SBarry Smith -  destroy - function to destroy the context
1177d25893d9SBarry Smith 
1178d25893d9SBarry Smith    Level: intermediate
1179d25893d9SBarry Smith 
1180f6dfbefdSBarry Smith    Note:
1181f6dfbefdSBarry Smith    This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level.
1182f6dfbefdSBarry Smith 
1183f6dfbefdSBarry Smith    Use `SNESSetApplicationContext()` to see the context immediately
1184f6dfbefdSBarry Smith 
1185f6dfbefdSBarry Smith    Fortran Note:
1186bb9467b5SJed Brown    This function is currently not available from Fortran.
1187bb9467b5SJed Brown 
1188f6dfbefdSBarry Smith .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()`
1189d25893d9SBarry Smith @*/
1190d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **))
1191d71ae5a4SJacob Faibussowitsch {
1192d25893d9SBarry Smith   PetscFunctionBegin;
1193d25893d9SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1194d25893d9SBarry Smith   snes->ops->usercompute = compute;
1195d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
11963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1197d25893d9SBarry Smith }
1198a847f771SSatish Balay 
1199b07ff414SBarry Smith /*@
1200f6dfbefdSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers.
12019b94acceSBarry Smith 
1202c3339decSBarry Smith    Logically Collective
1203fee21e36SBarry Smith 
1204c7afd0dbSLois Curfman McInnes    Input Parameters:
1205f6dfbefdSBarry Smith +  snes - the `SNES` context
1206c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1207c7afd0dbSLois Curfman McInnes 
120836851e7fSLois Curfman McInnes    Level: intermediate
120936851e7fSLois Curfman McInnes 
1210f6dfbefdSBarry Smith    Notes:
1211f6dfbefdSBarry Smith    Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function
1212f6dfbefdSBarry Smith    with `SNESGetApplicationContext()`
1213f6dfbefdSBarry Smith 
1214f6dfbefdSBarry Smith    To provide a function that computes the context for you use `SNESSetComputeApplicationContext()`
1215f6dfbefdSBarry Smith 
1216f6dfbefdSBarry Smith    Fortran Note:
121795452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1218daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1219daf670e6SBarry Smith 
1220f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()`
12219b94acceSBarry Smith @*/
1222d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP)
1223d71ae5a4SJacob Faibussowitsch {
1224b07ff414SBarry Smith   KSP ksp;
12251b2093e4SBarry Smith 
12263a40ed3dSBarry Smith   PetscFunctionBegin;
12270700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
12289566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
12299566063dSJacob Faibussowitsch   PetscCall(KSPSetApplicationContext(ksp, usrP));
12309b94acceSBarry Smith   snes->user = usrP;
12313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12329b94acceSBarry Smith }
123374679c65SBarry Smith 
1234b07ff414SBarry Smith /*@
12359b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
1236f6dfbefdSBarry Smith    nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()`
12379b94acceSBarry Smith 
1238c7afd0dbSLois Curfman McInnes    Not Collective
1239c7afd0dbSLois Curfman McInnes 
12409b94acceSBarry Smith    Input Parameter:
1241f6dfbefdSBarry Smith .  snes - `SNES` context
12429b94acceSBarry Smith 
12439b94acceSBarry Smith    Output Parameter:
12449b94acceSBarry Smith .  usrP - user context
12459b94acceSBarry Smith 
1246f6dfbefdSBarry Smith    Fortran Note:
124795452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1248daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1249daf670e6SBarry Smith 
125036851e7fSLois Curfman McInnes    Level: intermediate
125136851e7fSLois Curfman McInnes 
1252db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()`
12539b94acceSBarry Smith @*/
1254d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP)
1255d71ae5a4SJacob Faibussowitsch {
12563a40ed3dSBarry Smith   PetscFunctionBegin;
12570700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1258e71120c6SJed Brown   *(void **)usrP = snes->user;
12593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12609b94acceSBarry Smith }
126174679c65SBarry Smith 
12629b94acceSBarry Smith /*@
1263f6dfbefdSBarry Smith    SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian.
12643565c898SBarry Smith 
1265f6dfbefdSBarry Smith    Logically Collective on snes, the values must be the same on all MPI ranks
12663565c898SBarry Smith 
12673565c898SBarry Smith    Input Parameters:
1268f6dfbefdSBarry Smith +  snes - `SNES` context
1269f6dfbefdSBarry Smith .  mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used
1270f6dfbefdSBarry Smith -  mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored. With
1271f6dfbefdSBarry Smith    this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available
12723565c898SBarry Smith 
1273f6dfbefdSBarry Smith    Options Database Keys:
1274f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator
1275f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator
1276ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences.
1277ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow)
12783565c898SBarry Smith 
12793565c898SBarry Smith    Level: intermediate
12803565c898SBarry Smith 
1281f6dfbefdSBarry Smith    Note:
1282f6dfbefdSBarry Smith    SNES supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with
1283f6dfbefdSBarry Smith    finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object.
1284ec5066bdSBarry Smith 
1285f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()`
12863565c898SBarry Smith @*/
1287d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf)
1288d71ae5a4SJacob Faibussowitsch {
12893565c898SBarry Smith   PetscFunctionBegin;
12903565c898SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
129188b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes, mf_operator, 2);
129288b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes, mf, 3);
12934ddffce6SLisandro Dalcin   snes->mf          = mf_operator ? PETSC_TRUE : mf;
12943565c898SBarry Smith   snes->mf_operator = mf_operator;
12953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
12963565c898SBarry Smith }
12973565c898SBarry Smith 
12983565c898SBarry Smith /*@
1299f6dfbefdSBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix-free finite difference matrix vector products to apply the Jacobian.
13003565c898SBarry Smith 
1301f6dfbefdSBarry Smith    Not Collective, but the resulting flags will be the same on all MPI ranks
13023565c898SBarry Smith 
13033565c898SBarry Smith    Input Parameter:
1304f6dfbefdSBarry Smith .  snes - `SNES` context
13053565c898SBarry Smith 
13063565c898SBarry Smith    Output Parameters:
1307f6dfbefdSBarry Smith +  mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used
1308f6dfbefdSBarry Smith -  mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored
13093565c898SBarry Smith 
13103565c898SBarry Smith    Level: intermediate
13113565c898SBarry Smith 
1312f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()`
13133565c898SBarry Smith @*/
1314d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf)
1315d71ae5a4SJacob Faibussowitsch {
13163565c898SBarry Smith   PetscFunctionBegin;
13173565c898SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
13183565c898SBarry Smith   if (mf) *mf = snes->mf;
13193565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
13203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13213565c898SBarry Smith }
13223565c898SBarry Smith 
13233565c898SBarry Smith /*@
1324c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1325c8228a4eSBarry Smith    at this time.
13269b94acceSBarry Smith 
1327c7afd0dbSLois Curfman McInnes    Not Collective
1328c7afd0dbSLois Curfman McInnes 
13299b94acceSBarry Smith    Input Parameter:
1330f6dfbefdSBarry Smith .  snes - `SNES` context
13319b94acceSBarry Smith 
13329b94acceSBarry Smith    Output Parameter:
13339b94acceSBarry Smith .  iter - iteration number
13349b94acceSBarry Smith 
1335c8228a4eSBarry Smith    Notes:
1336c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1337c8228a4eSBarry Smith 
1338c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
1339f6dfbefdSBarry Smith    Jacobian at each `SNES` iteration). For example, the code
134008405cd6SLois Curfman McInnes .vb
134108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
134208405cd6SLois Curfman McInnes       if (!(it % 2)) {
134308405cd6SLois Curfman McInnes         [compute Jacobian here]
134408405cd6SLois Curfman McInnes       }
134508405cd6SLois Curfman McInnes .ve
1346f6dfbefdSBarry Smith    can be used in your function that computes the Jacobian to cause the Jacobian to be
1347f6dfbefdSBarry Smith    recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()`
1348c8228a4eSBarry Smith 
1349f6dfbefdSBarry Smith    After the `SNES` solve is complete this will return the number of nonlinear iterations used.
1350c04deec6SBarry Smith 
135136851e7fSLois Curfman McInnes    Level: intermediate
135236851e7fSLois Curfman McInnes 
1353f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()`
13549b94acceSBarry Smith @*/
1355d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter)
1356d71ae5a4SJacob Faibussowitsch {
13573a40ed3dSBarry Smith   PetscFunctionBegin;
13580700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
13594482741eSBarry Smith   PetscValidIntPointer(iter, 2);
13609b94acceSBarry Smith   *iter = snes->iter;
13613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13629b94acceSBarry Smith }
136374679c65SBarry Smith 
1364360c497dSPeter Brune /*@
1365360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1366360c497dSPeter Brune 
1367360c497dSPeter Brune    Not Collective
1368360c497dSPeter Brune 
1369d8d19677SJose E. Roman    Input Parameters:
1370f6dfbefdSBarry Smith +  snes - `SNES` context
1371a2b725a8SWilliam Gropp -  iter - iteration number
1372360c497dSPeter Brune 
1373360c497dSPeter Brune    Level: developer
1374360c497dSPeter Brune 
1375db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()`
1376360c497dSPeter Brune @*/
1377d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter)
1378d71ae5a4SJacob Faibussowitsch {
1379360c497dSPeter Brune   PetscFunctionBegin;
1380360c497dSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
13819566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes));
1382360c497dSPeter Brune   snes->iter = iter;
13839566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes));
13843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1385360c497dSPeter Brune }
1386360c497dSPeter Brune 
13879b94acceSBarry Smith /*@
1388b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
13899b94acceSBarry Smith    attempted by the nonlinear solver.
13909b94acceSBarry Smith 
1391c7afd0dbSLois Curfman McInnes    Not Collective
1392c7afd0dbSLois Curfman McInnes 
13939b94acceSBarry Smith    Input Parameter:
1394f6dfbefdSBarry Smith .  snes - `SNES` context
13959b94acceSBarry Smith 
13969b94acceSBarry Smith    Output Parameter:
13979b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
13989b94acceSBarry Smith 
1399f6dfbefdSBarry Smith    Note:
1400f6dfbefdSBarry Smith    This counter is reset to zero for each successive call to `SNESSolve()`.
1401c96a6f78SLois Curfman McInnes 
140236851e7fSLois Curfman McInnes    Level: intermediate
140336851e7fSLois Curfman McInnes 
1404f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1405db781477SPatrick Sanan           `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()`
14069b94acceSBarry Smith @*/
1407d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails)
1408d71ae5a4SJacob Faibussowitsch {
14093a40ed3dSBarry Smith   PetscFunctionBegin;
14100700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
14114482741eSBarry Smith   PetscValidIntPointer(nfails, 2);
141250ffb88aSMatthew Knepley   *nfails = snes->numFailures;
14133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
141450ffb88aSMatthew Knepley }
141550ffb88aSMatthew Knepley 
141650ffb88aSMatthew Knepley /*@
1417b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
1418f6dfbefdSBarry Smith    attempted by the nonlinear solver before it gives up and generates an error
141950ffb88aSMatthew Knepley 
142050ffb88aSMatthew Knepley    Not Collective
142150ffb88aSMatthew Knepley 
142250ffb88aSMatthew Knepley    Input Parameters:
1423f6dfbefdSBarry Smith +  snes     - `SNES` context
142450ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
142550ffb88aSMatthew Knepley 
142650ffb88aSMatthew Knepley    Level: intermediate
142750ffb88aSMatthew Knepley 
1428f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1429db781477SPatrick Sanan           `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
143050ffb88aSMatthew Knepley @*/
1431d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
1432d71ae5a4SJacob Faibussowitsch {
143350ffb88aSMatthew Knepley   PetscFunctionBegin;
14340700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
143550ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
14363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
143750ffb88aSMatthew Knepley }
143850ffb88aSMatthew Knepley 
143950ffb88aSMatthew Knepley /*@
1440b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
1441f6dfbefdSBarry Smith    attempted by the nonlinear solver before it gives up and generates an error
144250ffb88aSMatthew Knepley 
144350ffb88aSMatthew Knepley    Not Collective
144450ffb88aSMatthew Knepley 
144550ffb88aSMatthew Knepley    Input Parameter:
144650ffb88aSMatthew Knepley .  snes     - SNES context
144750ffb88aSMatthew Knepley 
144850ffb88aSMatthew Knepley    Output Parameter:
144950ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
145050ffb88aSMatthew Knepley 
145150ffb88aSMatthew Knepley    Level: intermediate
145250ffb88aSMatthew Knepley 
1453f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1454db781477SPatrick Sanan           `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
145550ffb88aSMatthew Knepley @*/
1456d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
1457d71ae5a4SJacob Faibussowitsch {
145850ffb88aSMatthew Knepley   PetscFunctionBegin;
14590700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
14604482741eSBarry Smith   PetscValidIntPointer(maxFails, 2);
146150ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
14623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14639b94acceSBarry Smith }
1464a847f771SSatish Balay 
14652541af92SBarry Smith /*@
14662541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
1467f6dfbefdSBarry Smith      done by the `SNES` object
14682541af92SBarry Smith 
14692541af92SBarry Smith    Not Collective
14702541af92SBarry Smith 
14712541af92SBarry Smith    Input Parameter:
1472f6dfbefdSBarry Smith .  snes     - `SNES` context
14732541af92SBarry Smith 
14742541af92SBarry Smith    Output Parameter:
14752541af92SBarry Smith .  nfuncs - number of evaluations
14762541af92SBarry Smith 
14772541af92SBarry Smith    Level: intermediate
14782541af92SBarry Smith 
1479f6dfbefdSBarry Smith    Note:
1480f6dfbefdSBarry Smith     Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used.
1481971e163fSPeter Brune 
1482f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()`
14832541af92SBarry Smith @*/
1484d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
1485d71ae5a4SJacob Faibussowitsch {
14862541af92SBarry Smith   PetscFunctionBegin;
14870700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
14882541af92SBarry Smith   PetscValidIntPointer(nfuncs, 2);
14892541af92SBarry Smith   *nfuncs = snes->nfuncs;
14903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
14912541af92SBarry Smith }
14922541af92SBarry Smith 
14933d4c4710SBarry Smith /*@
14943d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
14953d4c4710SBarry Smith    linear solvers.
14963d4c4710SBarry Smith 
14973d4c4710SBarry Smith    Not Collective
14983d4c4710SBarry Smith 
14993d4c4710SBarry Smith    Input Parameter:
1500f6dfbefdSBarry Smith .  snes - `SNES` context
15013d4c4710SBarry Smith 
15023d4c4710SBarry Smith    Output Parameter:
15033d4c4710SBarry Smith .  nfails - number of failed solves
15043d4c4710SBarry Smith 
1505f6dfbefdSBarry Smith    Options Database Key:
15069d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15079d85da0cSMatthew G. Knepley 
1508f6dfbefdSBarry Smith    Level: intermediate
1509f6dfbefdSBarry Smith 
1510f6dfbefdSBarry Smith    Note:
1511f6dfbefdSBarry Smith    This counter is reset to zero for each successive call to `SNESSolve()`.
15123d4c4710SBarry Smith 
1513db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`
15143d4c4710SBarry Smith @*/
1515d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails)
1516d71ae5a4SJacob Faibussowitsch {
15173d4c4710SBarry Smith   PetscFunctionBegin;
15180700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
15193d4c4710SBarry Smith   PetscValidIntPointer(nfails, 2);
15203d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
15213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15223d4c4710SBarry Smith }
15233d4c4710SBarry Smith 
15243d4c4710SBarry Smith /*@
15253d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
1526f6dfbefdSBarry Smith    allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE`
15273d4c4710SBarry Smith 
1528c3339decSBarry Smith    Logically Collective
15293d4c4710SBarry Smith 
15303d4c4710SBarry Smith    Input Parameters:
1531f6dfbefdSBarry Smith +  snes     - `SNES` context
15323d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
15333d4c4710SBarry Smith 
15343d4c4710SBarry Smith    Level: intermediate
15353d4c4710SBarry Smith 
1536f6dfbefdSBarry Smith    Options Database Key:
15379d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15389d85da0cSMatthew G. Knepley 
1539f6dfbefdSBarry Smith    Note:
1540f6dfbefdSBarry Smith     By default this is 0; that is `SNES` returns on the first failed linear solve
15413d4c4710SBarry Smith 
1542f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`
15433d4c4710SBarry Smith @*/
1544d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
1545d71ae5a4SJacob Faibussowitsch {
15463d4c4710SBarry Smith   PetscFunctionBegin;
15470700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1548c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, maxFails, 2);
15493d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
15503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15513d4c4710SBarry Smith }
15523d4c4710SBarry Smith 
15533d4c4710SBarry Smith /*@
15543d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
1555f6dfbefdSBarry Smith      are allowed before `SNES` returns as unsuccessful
15563d4c4710SBarry Smith 
15573d4c4710SBarry Smith    Not Collective
15583d4c4710SBarry Smith 
15593d4c4710SBarry Smith    Input Parameter:
1560f6dfbefdSBarry Smith .  snes     - `SNES` context
15613d4c4710SBarry Smith 
15623d4c4710SBarry Smith    Output Parameter:
15633d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
15643d4c4710SBarry Smith 
15653d4c4710SBarry Smith    Level: intermediate
15663d4c4710SBarry Smith 
1567f6dfbefdSBarry Smith    Note:
1568f6dfbefdSBarry Smith     By default this is 1; that is `SNES` returns on the first failed linear solve
15693d4c4710SBarry Smith 
1570f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`,
15713d4c4710SBarry Smith @*/
1572d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
1573d71ae5a4SJacob Faibussowitsch {
15743d4c4710SBarry Smith   PetscFunctionBegin;
15750700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
15763d4c4710SBarry Smith   PetscValidIntPointer(maxFails, 2);
15773d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
15783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
15793d4c4710SBarry Smith }
15803d4c4710SBarry Smith 
1581c96a6f78SLois Curfman McInnes /*@
1582b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1583c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1584c96a6f78SLois Curfman McInnes 
1585c7afd0dbSLois Curfman McInnes    Not Collective
1586c7afd0dbSLois Curfman McInnes 
1587c96a6f78SLois Curfman McInnes    Input Parameter:
1588f6dfbefdSBarry Smith .  snes - `SNES` context
1589c96a6f78SLois Curfman McInnes 
1590c96a6f78SLois Curfman McInnes    Output Parameter:
1591c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1592c96a6f78SLois Curfman McInnes 
1593c96a6f78SLois Curfman McInnes    Notes:
1594f6dfbefdSBarry Smith    This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used.
1595c96a6f78SLois Curfman McInnes 
1596f6dfbefdSBarry 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
1597f6dfbefdSBarry Smith    then call `KSPGetIterationNumber()` after the failed solve.
1598010be392SBarry Smith 
159936851e7fSLois Curfman McInnes    Level: intermediate
160036851e7fSLois Curfman McInnes 
1601f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()`
1602c96a6f78SLois Curfman McInnes @*/
1603d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits)
1604d71ae5a4SJacob Faibussowitsch {
16053a40ed3dSBarry Smith   PetscFunctionBegin;
16060700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
16074482741eSBarry Smith   PetscValidIntPointer(lits, 2);
1608c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
16093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1610c96a6f78SLois Curfman McInnes }
1611c96a6f78SLois Curfman McInnes 
1612971e163fSPeter Brune /*@
1613971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1614f6dfbefdSBarry Smith    are reset every time `SNESSolve()` is called.
1615971e163fSPeter Brune 
1616c3339decSBarry Smith    Logically Collective
1617971e163fSPeter Brune 
1618d8d19677SJose E. Roman    Input Parameters:
1619f6dfbefdSBarry Smith +  snes - `SNES` context
1620f6dfbefdSBarry Smith -  reset - whether to reset the counters or not, defaults to `PETSC_TRUE`
1621971e163fSPeter Brune 
1622971e163fSPeter Brune    Level: developer
1623971e163fSPeter Brune 
1624db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()`
1625971e163fSPeter Brune @*/
1626d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset)
1627d71ae5a4SJacob Faibussowitsch {
1628971e163fSPeter Brune   PetscFunctionBegin;
1629971e163fSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1630971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes, reset, 2);
1631971e163fSPeter Brune   snes->counters_reset = reset;
16323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1633971e163fSPeter Brune }
1634971e163fSPeter Brune 
16352999313aSBarry Smith /*@
1636f6dfbefdSBarry Smith    SNESSetKSP - Sets a `KSP` context for the `SNES` object to use
16372999313aSBarry Smith 
1638f6dfbefdSBarry Smith    Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm
16392999313aSBarry Smith 
16402999313aSBarry Smith    Input Parameters:
1641f6dfbefdSBarry Smith +  snes - the `SNES` context
1642f6dfbefdSBarry Smith -  ksp - the `KSP` context
16432999313aSBarry Smith 
16442999313aSBarry Smith    Notes:
1645f6dfbefdSBarry Smith    The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()`
16462999313aSBarry Smith    so this routine is rarely needed.
16472999313aSBarry Smith 
1648f6dfbefdSBarry Smith    The `KSP` object that is already in the `SNES` object has its reference count
16492999313aSBarry Smith    decreased by one.
16502999313aSBarry Smith 
16512999313aSBarry Smith    Level: developer
16522999313aSBarry Smith 
1653f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
16542999313aSBarry Smith @*/
1655d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp)
1656d71ae5a4SJacob Faibussowitsch {
16572999313aSBarry Smith   PetscFunctionBegin;
16580700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
16590700a824SBarry Smith   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2);
16602999313aSBarry Smith   PetscCheckSameComm(snes, 1, ksp, 2);
16619566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ksp));
16629566063dSJacob Faibussowitsch   if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp));
16632999313aSBarry Smith   snes->ksp = ksp;
16643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
16652999313aSBarry Smith }
16662999313aSBarry Smith 
166752baeb72SSatish Balay /*@
16689b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
16699b94acceSBarry Smith 
1670d083f849SBarry Smith    Collective
1671c7afd0dbSLois Curfman McInnes 
1672f6dfbefdSBarry Smith    Input Parameter:
1673906ed7ccSBarry Smith .  comm - MPI communicator
16749b94acceSBarry Smith 
16759b94acceSBarry Smith    Output Parameter:
16769b94acceSBarry Smith .  outsnes - the new SNES context
16779b94acceSBarry Smith 
1678c7afd0dbSLois Curfman McInnes    Options Database Keys:
1679c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1680c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1681c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1682c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1683c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1684c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1685c1f60f51SBarry Smith 
168636851e7fSLois Curfman McInnes    Level: beginner
168736851e7fSLois Curfman McInnes 
168895452b02SPatrick Sanan    Developer Notes:
1689f6dfbefdSBarry Smith    `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is
1690efd4aadfSBarry Smith    unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1691f6dfbefdSBarry Smith    particular method does use `KSP` and regulates if the information about the `KSP` is printed
1692f6dfbefdSBarry Smith    in `SNESView()`.
1693efd4aadfSBarry Smith 
1694f6dfbefdSBarry Smith    `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused
1695f6dfbefdSBarry Smith    by help messages about meaningless `SNES` options.
1696f6dfbefdSBarry Smith 
1697f6dfbefdSBarry Smith    `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should
1698efd4aadfSBarry Smith                     be fixed.
1699efd4aadfSBarry Smith 
1700f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
17019b94acceSBarry Smith @*/
1702d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes)
1703d71ae5a4SJacob Faibussowitsch {
17049b94acceSBarry Smith   SNES       snes;
1705fa9f3622SBarry Smith   SNESKSPEW *kctx;
170637fcc0dbSBarry Smith 
17073a40ed3dSBarry Smith   PetscFunctionBegin;
1708ed1caa07SMatthew Knepley   PetscValidPointer(outsnes, 2);
17090298fd71SBarry Smith   *outsnes = NULL;
17109566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
17118ba1e511SMatthew Knepley 
17129566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView));
17137adad957SLisandro Dalcin 
17148d359177SBarry Smith   snes->ops->converged = SNESConvergedDefault;
17152c155ee1SBarry Smith   snes->usesksp        = PETSC_TRUE;
171688976e71SPeter Brune   snes->tolerancesset  = PETSC_FALSE;
17179b94acceSBarry Smith   snes->max_its        = 50;
17189750a799SBarry Smith   snes->max_funcs      = 10000;
17199b94acceSBarry Smith   snes->norm           = 0.0;
1720c1e67a49SFande Kong   snes->xnorm          = 0.0;
1721c1e67a49SFande Kong   snes->ynorm          = 0.0;
1722365a6726SPeter Brune   snes->normschedule   = SNES_NORM_ALWAYS;
17236c67d002SPeter Brune   snes->functype       = SNES_FUNCTION_DEFAULT;
17243a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17253a2046daSBarry Smith   snes->rtol = 1.e-5;
17263a2046daSBarry Smith #else
1727b4874afaSBarry Smith   snes->rtol = 1.e-8;
17283a2046daSBarry Smith #endif
1729b4874afaSBarry Smith   snes->ttol = 0.0;
17303a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17313a2046daSBarry Smith   snes->abstol = 1.e-25;
17323a2046daSBarry Smith #else
173370441072SBarry Smith   snes->abstol = 1.e-50;
17343a2046daSBarry Smith #endif
17357cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
17367cd0ae37SLisandro Dalcin   snes->stol = 1.e-5;
17377cd0ae37SLisandro Dalcin #else
1738c60f73f4SPeter Brune   snes->stol = 1.e-8;
17397cd0ae37SLisandro Dalcin #endif
17403a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17413a2046daSBarry Smith   snes->deltatol = 1.e-6;
17423a2046daSBarry Smith #else
17434b27c08aSLois Curfman McInnes   snes->deltatol = 1.e-12;
17443a2046daSBarry Smith #endif
1745e37c518bSBarry Smith   snes->divtol               = 1.e4;
1746e37c518bSBarry Smith   snes->rnorm0               = 0;
17479b94acceSBarry Smith   snes->nfuncs               = 0;
174850ffb88aSMatthew Knepley   snes->numFailures          = 0;
174950ffb88aSMatthew Knepley   snes->maxFailures          = 1;
17507a00f4a9SLois Curfman McInnes   snes->linear_its           = 0;
1751e35cf81dSBarry Smith   snes->lagjacobian          = 1;
175237ec4e1aSPeter Brune   snes->jac_iter             = 0;
175337ec4e1aSPeter Brune   snes->lagjac_persist       = PETSC_FALSE;
1754a8054027SBarry Smith   snes->lagpreconditioner    = 1;
175537ec4e1aSPeter Brune   snes->pre_iter             = 0;
175637ec4e1aSPeter Brune   snes->lagpre_persist       = PETSC_FALSE;
1757639f9d9dSBarry Smith   snes->numbermonitors       = 0;
1758c4421ceaSFande Kong   snes->numberreasonviews    = 0;
17599e5d0892SLisandro Dalcin   snes->data                 = NULL;
17604dc4c822SBarry Smith   snes->setupcalled          = PETSC_FALSE;
1761186905e3SBarry Smith   snes->ksp_ewconv           = PETSC_FALSE;
17626f24a144SLois Curfman McInnes   snes->nwork                = 0;
17639e5d0892SLisandro Dalcin   snes->work                 = NULL;
176458c9b817SLisandro Dalcin   snes->nvwork               = 0;
17659e5d0892SLisandro Dalcin   snes->vwork                = NULL;
1766758f92a0SBarry Smith   snes->conv_hist_len        = 0;
1767758f92a0SBarry Smith   snes->conv_hist_max        = 0;
17680298fd71SBarry Smith   snes->conv_hist            = NULL;
17690298fd71SBarry Smith   snes->conv_hist_its        = NULL;
1770758f92a0SBarry Smith   snes->conv_hist_reset      = PETSC_TRUE;
1771971e163fSPeter Brune   snes->counters_reset       = PETSC_TRUE;
1772e4ed7901SPeter Brune   snes->vec_func_init_set    = PETSC_FALSE;
1773184914b5SBarry Smith   snes->reason               = SNES_CONVERGED_ITERATING;
1774efd4aadfSBarry Smith   snes->npcside              = PC_RIGHT;
1775b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled = 0;
1776c40d0f55SPeter Brune 
1777d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1778d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1779d8f46077SPeter Brune   snes->mf_version  = 1;
1780d8f46077SPeter Brune 
17813d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
17823d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
17833d4c4710SBarry Smith 
1784349187a7SBarry Smith   snes->vizerotolerance     = 1.e-8;
178576bd3646SJed Brown   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1786349187a7SBarry Smith 
17874fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
17884fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
17894fc747eaSLawrence Mitchell 
17909b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
17914dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&kctx));
1792f5af7f23SKarl Rupp 
17939b94acceSBarry Smith   snes->kspconvctx  = (void *)kctx;
17949b94acceSBarry Smith   kctx->version     = 2;
17950f0abf79SStefano Zampini   kctx->rtol_0      = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but
17969b94acceSBarry Smith                              this was too large for some test cases */
179775567043SBarry Smith   kctx->rtol_last   = 0.0;
17980f0abf79SStefano Zampini   kctx->rtol_max    = 0.9;
17999b94acceSBarry Smith   kctx->gamma       = 1.0;
18000f0abf79SStefano Zampini   kctx->alpha       = 0.5 * (1.0 + PetscSqrtReal(5.0));
180171f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
18020f0abf79SStefano Zampini   kctx->threshold   = 0.1;
180375567043SBarry Smith   kctx->lresid_last = 0.0;
180475567043SBarry Smith   kctx->norm_last   = 0.0;
18059b94acceSBarry Smith 
18060f0abf79SStefano Zampini   kctx->rk_last     = 0.0;
18070f0abf79SStefano Zampini   kctx->rk_last_2   = 0.0;
18080f0abf79SStefano Zampini   kctx->rtol_last_2 = 0.0;
18090f0abf79SStefano Zampini   kctx->v4_p1       = 0.1;
18100f0abf79SStefano Zampini   kctx->v4_p2       = 0.4;
18110f0abf79SStefano Zampini   kctx->v4_p3       = 0.7;
18120f0abf79SStefano Zampini   kctx->v4_m1       = 0.8;
18130f0abf79SStefano Zampini   kctx->v4_m2       = 0.5;
18140f0abf79SStefano Zampini   kctx->v4_m3       = 0.1;
18150f0abf79SStefano Zampini   kctx->v4_m4       = 0.5;
18160f0abf79SStefano Zampini 
18179b94acceSBarry Smith   *outsnes = snes;
18183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18199b94acceSBarry Smith }
18209b94acceSBarry Smith 
182188f0584fSBarry Smith /*MC
1822f6dfbefdSBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()`
182388f0584fSBarry Smith 
182488f0584fSBarry Smith      Synopsis:
1825411c0326SBarry Smith      #include "petscsnes.h"
1826411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
182788f0584fSBarry Smith 
1828c3339decSBarry Smith      Collective
18291843f636SBarry Smith 
183088f0584fSBarry Smith      Input Parameters:
1831f6dfbefdSBarry Smith +     snes - the `SNES` context
183288f0584fSBarry Smith .     x    - state at which to evaluate residual
1833f6dfbefdSBarry Smith -     ctx     - optional user-defined function context, passed in with `SNESSetFunction()`
183488f0584fSBarry Smith 
183588f0584fSBarry Smith      Output Parameter:
183688f0584fSBarry Smith .     f  - vector to put residual (function value)
183788f0584fSBarry Smith 
1838878cb397SSatish Balay    Level: intermediate
1839878cb397SSatish Balay 
1840db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`
184188f0584fSBarry Smith M*/
184288f0584fSBarry Smith 
18439b94acceSBarry Smith /*@C
18449b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
1845f6dfbefdSBarry Smith    vector for use by the `SNES` routines in solving systems of nonlinear
18469b94acceSBarry Smith    equations.
18479b94acceSBarry Smith 
1848c3339decSBarry Smith    Logically Collective
1849fee21e36SBarry Smith 
1850c7afd0dbSLois Curfman McInnes    Input Parameters:
1851f6dfbefdSBarry Smith +  snes - the `SNES` context
18526b7fb656SBarry Smith .  r - vector to store function values, may be NULL
1853f6dfbefdSBarry Smith .  f - function evaluation routine; see `SNESFunction` for calling sequence details
1854c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
18550298fd71SBarry Smith          function evaluation routine (may be NULL)
18569b94acceSBarry Smith 
185736851e7fSLois Curfman McInnes    Level: beginner
185836851e7fSLois Curfman McInnes 
1859f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction`
18609b94acceSBarry Smith @*/
1861d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx)
1862d71ae5a4SJacob Faibussowitsch {
18636cab3a1bSJed Brown   DM dm;
18646cab3a1bSJed Brown 
18653a40ed3dSBarry Smith   PetscFunctionBegin;
18660700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1867d2a683ecSLisandro Dalcin   if (r) {
1868d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r, VEC_CLASSID, 2);
1869d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes, 1, r, 2);
18709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)r));
18719566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_func));
187285385478SLisandro Dalcin     snes->vec_func = r;
1873d2a683ecSLisandro Dalcin   }
18749566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
18759566063dSJacob Faibussowitsch   PetscCall(DMSNESSetFunction(dm, f, ctx));
187648a46eb9SPierre Jolivet   if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx));
18773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
18789b94acceSBarry Smith }
18799b94acceSBarry Smith 
1880e4ed7901SPeter Brune /*@C
1881e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1882f6dfbefdSBarry Smith    initial function value at the initialization of the method.  In some
1883e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1884f6dfbefdSBarry Smith    `SNESSolve()`.  This function allows one to avoid a redundant call
1885f6dfbefdSBarry Smith    to `SNESComputeFunction()` in that case.
1886e4ed7901SPeter Brune 
1887c3339decSBarry Smith    Logically Collective
1888e4ed7901SPeter Brune 
1889e4ed7901SPeter Brune    Input Parameters:
1890f6dfbefdSBarry Smith +  snes - the `SNES` context
1891e4ed7901SPeter Brune -  f - vector to store function value
1892e4ed7901SPeter Brune 
1893e4ed7901SPeter Brune    Notes:
1894e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1895e4ed7901SPeter Brune 
1896f6dfbefdSBarry Smith    This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning.
1897e4ed7901SPeter Brune 
1898e4ed7901SPeter Brune    Level: developer
1899e4ed7901SPeter Brune 
1900f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()`
1901e4ed7901SPeter Brune @*/
1902d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f)
1903d71ae5a4SJacob Faibussowitsch {
1904e4ed7901SPeter Brune   Vec vec_func;
1905e4ed7901SPeter Brune 
1906e4ed7901SPeter Brune   PetscFunctionBegin;
1907e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1908e4ed7901SPeter Brune   PetscValidHeaderSpecific(f, VEC_CLASSID, 2);
1909e4ed7901SPeter Brune   PetscCheckSameComm(snes, 1, f, 2);
1910efd4aadfSBarry Smith   if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1911902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
19123ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
1913902f982fSPeter Brune   }
19149566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL));
19159566063dSJacob Faibussowitsch   PetscCall(VecCopy(f, vec_func));
1916f5af7f23SKarl Rupp 
1917217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
19183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1919e4ed7901SPeter Brune }
1920e4ed7901SPeter Brune 
1921534ebe21SPeter Brune /*@
1922f6dfbefdSBarry Smith    SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring
1923f6dfbefdSBarry Smith    of the `SNES` method, when norms are computed in the solving process
1924534ebe21SPeter Brune 
1925c3339decSBarry Smith    Logically Collective
1926534ebe21SPeter Brune 
1927534ebe21SPeter Brune    Input Parameters:
1928f6dfbefdSBarry Smith +  snes - the `SNES` context
1929365a6726SPeter Brune -  normschedule - the frequency of norm computation
1930534ebe21SPeter Brune 
1931517f1916SMatthew G. Knepley    Options Database Key:
193267b8a455SSatish Balay .  -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule
1933517f1916SMatthew G. Knepley 
1934534ebe21SPeter Brune    Notes:
1935f6dfbefdSBarry Smith    Only certain `SNES` methods support certain `SNESNormSchedules`.  Most require evaluation
1936534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1937534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1938f6dfbefdSBarry Smith    `SNESNGS` and the like do not require the norm of the function to be computed, and therefore
1939534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1940534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1941534ebe21SPeter Brune    their solution.
1942534ebe21SPeter Brune 
1943f6dfbefdSBarry Smith    Level: advanced
1944534ebe21SPeter Brune 
1945f6dfbefdSBarry Smith .seealso: `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1946534ebe21SPeter Brune @*/
1947d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1948d71ae5a4SJacob Faibussowitsch {
1949534ebe21SPeter Brune   PetscFunctionBegin;
1950534ebe21SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1951365a6726SPeter Brune   snes->normschedule = normschedule;
19523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1953534ebe21SPeter Brune }
1954534ebe21SPeter Brune 
1955534ebe21SPeter Brune /*@
1956f6dfbefdSBarry Smith    SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring
1957f6dfbefdSBarry Smith    of the `SNES` method.
1958534ebe21SPeter Brune 
1959c3339decSBarry Smith    Logically Collective
1960534ebe21SPeter Brune 
1961534ebe21SPeter Brune    Input Parameters:
1962f6dfbefdSBarry Smith +  snes - the `SNES` context
1963365a6726SPeter Brune -  normschedule - the type of the norm used
1964534ebe21SPeter Brune 
1965534ebe21SPeter Brune    Level: advanced
1966534ebe21SPeter Brune 
1967f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1968534ebe21SPeter Brune @*/
1969d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1970d71ae5a4SJacob Faibussowitsch {
1971534ebe21SPeter Brune   PetscFunctionBegin;
1972534ebe21SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1973365a6726SPeter Brune   *normschedule = snes->normschedule;
19743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1975534ebe21SPeter Brune }
1976534ebe21SPeter Brune 
1977c5ce4427SMatthew G. Knepley /*@
1978c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1979c5ce4427SMatthew G. Knepley 
1980c3339decSBarry Smith   Logically Collective
1981c5ce4427SMatthew G. Knepley 
1982c5ce4427SMatthew G. Knepley   Input Parameters:
1983f6dfbefdSBarry Smith +  snes - the `SNES` context
1984f6dfbefdSBarry Smith -  norm - the value of the norm
1985c5ce4427SMatthew G. Knepley 
1986c5ce4427SMatthew G. Knepley   Level: developer
1987c5ce4427SMatthew G. Knepley 
1988f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1989c5ce4427SMatthew G. Knepley @*/
1990d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1991d71ae5a4SJacob Faibussowitsch {
1992c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1993c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
1994c5ce4427SMatthew G. Knepley   snes->norm = norm;
19953ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1996c5ce4427SMatthew G. Knepley }
1997c5ce4427SMatthew G. Knepley 
1998c5ce4427SMatthew G. Knepley /*@
1999c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
2000c5ce4427SMatthew G. Knepley 
2001c5ce4427SMatthew G. Knepley   Not Collective
2002c5ce4427SMatthew G. Knepley 
2003c5ce4427SMatthew G. Knepley   Input Parameter:
2004f6dfbefdSBarry Smith . snes - the `SNES` context
2005c5ce4427SMatthew G. Knepley 
2006c5ce4427SMatthew G. Knepley   Output Parameter:
2007c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
2008c5ce4427SMatthew G. Knepley 
2009c5ce4427SMatthew G. Knepley   Level: developer
2010c5ce4427SMatthew G. Knepley 
2011f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2012c5ce4427SMatthew G. Knepley @*/
2013d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
2014d71ae5a4SJacob Faibussowitsch {
2015c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
2016c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2017dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 2);
2018c5ce4427SMatthew G. Knepley   *norm = snes->norm;
20193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2020c5ce4427SMatthew G. Knepley }
2021c5ce4427SMatthew G. Knepley 
2022c1e67a49SFande Kong /*@
2023f6dfbefdSBarry Smith   SNESGetUpdateNorm - Gets the last computed norm of the solution update
2024c1e67a49SFande Kong 
2025c1e67a49SFande Kong   Not Collective
2026c1e67a49SFande Kong 
2027c1e67a49SFande Kong   Input Parameter:
2028f6dfbefdSBarry Smith . snes - the `SNES` context
2029c1e67a49SFande Kong 
2030c1e67a49SFande Kong   Output Parameter:
2031c1e67a49SFande Kong . ynorm - the last computed update norm
2032c1e67a49SFande Kong 
2033c1e67a49SFande Kong   Level: developer
2034c1e67a49SFande Kong 
2035f6dfbefdSBarry Smith   Note:
2036f6dfbefdSBarry Smith   The new solution is the current solution plus the update, so this norm is an indication of the size of the update
2037f6dfbefdSBarry Smith 
2038f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`
2039c1e67a49SFande Kong @*/
2040d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2041d71ae5a4SJacob Faibussowitsch {
2042c1e67a49SFande Kong   PetscFunctionBegin;
2043c1e67a49SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2044dadcf809SJacob Faibussowitsch   PetscValidRealPointer(ynorm, 2);
2045c1e67a49SFande Kong   *ynorm = snes->ynorm;
20463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2047c1e67a49SFande Kong }
2048c1e67a49SFande Kong 
2049c1e67a49SFande Kong /*@
20504591eaf2SFande Kong   SNESGetSolutionNorm - Gets the last computed norm of the solution
2051c1e67a49SFande Kong 
2052c1e67a49SFande Kong   Not Collective
2053c1e67a49SFande Kong 
2054c1e67a49SFande Kong   Input Parameter:
2055f6dfbefdSBarry Smith . snes - the `SNES` context
2056c1e67a49SFande Kong 
2057c1e67a49SFande Kong   Output Parameter:
2058c1e67a49SFande Kong . xnorm - the last computed solution norm
2059c1e67a49SFande Kong 
2060c1e67a49SFande Kong   Level: developer
2061c1e67a49SFande Kong 
2062f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()`
2063c1e67a49SFande Kong @*/
2064d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2065d71ae5a4SJacob Faibussowitsch {
2066c1e67a49SFande Kong   PetscFunctionBegin;
2067c1e67a49SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2068dadcf809SJacob Faibussowitsch   PetscValidRealPointer(xnorm, 2);
2069c1e67a49SFande Kong   *xnorm = snes->xnorm;
20703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2071c1e67a49SFande Kong }
2072c1e67a49SFande Kong 
207347073ea2SPeter Brune /*@C
2074f6dfbefdSBarry Smith    SNESSetFunctionType - Sets the `SNESFunctionType`
2075f6dfbefdSBarry Smith    of the `SNES` method.
207647073ea2SPeter Brune 
2077c3339decSBarry Smith    Logically Collective
207847073ea2SPeter Brune 
207947073ea2SPeter Brune    Input Parameters:
2080f6dfbefdSBarry Smith +  snes - the `SNES` context
2081f6dfbefdSBarry Smith -  type - the function type
208247073ea2SPeter Brune 
208347073ea2SPeter Brune    Level: developer
208447073ea2SPeter Brune 
2085f6dfbefdSBarry Smith    Notes:
2086f6dfbefdSBarry Smith    Possible values of the function type
2087f6dfbefdSBarry Smith +  `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType`
2088f6dfbefdSBarry Smith .  `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()`
2089f6dfbefdSBarry Smith -  `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()`
2090f6dfbefdSBarry Smith 
2091f6dfbefdSBarry Smith    Different `SNESType`s use this value in different ways
2092f6dfbefdSBarry Smith 
2093f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
209447073ea2SPeter Brune @*/
2095d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type)
2096d71ae5a4SJacob Faibussowitsch {
209747073ea2SPeter Brune   PetscFunctionBegin;
209847073ea2SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
209947073ea2SPeter Brune   snes->functype = type;
21003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
210147073ea2SPeter Brune }
210247073ea2SPeter Brune 
210347073ea2SPeter Brune /*@C
2104f6dfbefdSBarry Smith    SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()`
210547073ea2SPeter Brune    of the SNES method.
210647073ea2SPeter Brune 
2107c3339decSBarry Smith    Logically Collective
210847073ea2SPeter Brune 
210947073ea2SPeter Brune    Input Parameters:
2110f6dfbefdSBarry Smith +  snes - the `SNES` context
2111f6dfbefdSBarry Smith -  type - the type of the function evaluation, see `SNESSetFunctionType()`
211247073ea2SPeter Brune 
211347073ea2SPeter Brune    Level: advanced
211447073ea2SPeter Brune 
2115f6dfbefdSBarry Smith .seealso: `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
211647073ea2SPeter Brune @*/
2117d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type)
2118d71ae5a4SJacob Faibussowitsch {
211947073ea2SPeter Brune   PetscFunctionBegin;
212047073ea2SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
212147073ea2SPeter Brune   *type = snes->functype;
21223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2123534ebe21SPeter Brune }
2124534ebe21SPeter Brune 
2125bf388a1fSBarry Smith /*MC
2126f6dfbefdSBarry Smith     SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function
2127bf388a1fSBarry Smith 
2128bf388a1fSBarry Smith      Synopsis:
2129aaa7dc30SBarry Smith      #include <petscsnes.h>
2130be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
2131bf388a1fSBarry Smith 
2132c3339decSBarry Smith      Collective
21331843f636SBarry Smith 
21341843f636SBarry Smith      Input Parameters:
2135bf388a1fSBarry Smith +  X   - solution vector
2136bf388a1fSBarry Smith .  B   - RHS vector
2137bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
2138bf388a1fSBarry Smith 
21391843f636SBarry Smith      Output Parameter:
21401843f636SBarry Smith .  X   - solution vector
21411843f636SBarry Smith 
2142878cb397SSatish Balay    Level: intermediate
2143878cb397SSatish Balay 
2144f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()`
2145bf388a1fSBarry Smith M*/
2146bf388a1fSBarry Smith 
2147c79ef259SPeter Brune /*@C
2148be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2149c79ef259SPeter Brune    use with composed nonlinear solvers.
2150c79ef259SPeter Brune 
2151c79ef259SPeter Brune    Input Parameters:
2152c79ef259SPeter Brune +  snes   - the SNES context
2153f6dfbefdSBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction`
2154c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
21550298fd71SBarry Smith             smoother evaluation routine (may be NULL)
2156c79ef259SPeter Brune 
2157f6dfbefdSBarry Smith    Calling sequence of f:
2158f6dfbefdSBarry Smith $  PetscErrorCode f(SNES snes,Vec X,Vec B,void *ctx);
2159f6dfbefdSBarry Smith 
2160f6dfbefdSBarry Smith    Arguments of f:
2161f6dfbefdSBarry Smith +  snes - the `SNES` context
2162f6dfbefdSBarry Smith .  X - the current solution
2163f6dfbefdSBarry Smith .  B - the right hand side vector (which may be NULL)
2164f6dfbefdSBarry Smith -  ctx - a user provided context
2165f6dfbefdSBarry Smith 
2166f6dfbefdSBarry Smith    Note:
2167f6dfbefdSBarry Smith    The `SNESNGS` routines are used by the composed nonlinear solver to generate
2168f6dfbefdSBarry Smith     a problem appropriate update to the solution, particularly `SNESFAS`.
2169c79ef259SPeter Brune 
2170d28543b3SPeter Brune    Level: intermediate
2171c79ef259SPeter Brune 
2172f6dfbefdSBarry Smith .seealso: `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()`
2173c79ef259SPeter Brune @*/
2174d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx)
2175d71ae5a4SJacob Faibussowitsch {
21766cab3a1bSJed Brown   DM dm;
21776cab3a1bSJed Brown 
2178646217ecSPeter Brune   PetscFunctionBegin;
21796cab3a1bSJed Brown   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
21809566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
21819566063dSJacob Faibussowitsch   PetscCall(DMSNESSetNGS(dm, f, ctx));
21823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2183646217ecSPeter Brune }
2184646217ecSPeter Brune 
2185bbc1464cSBarry Smith /*
2186bbc1464cSBarry Smith      This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be
2187bbc1464cSBarry Smith    changed during the KSPSolve()
2188bbc1464cSBarry Smith */
2189d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx)
2190d71ae5a4SJacob Faibussowitsch {
2191bbc1464cSBarry Smith   DM     dm;
2192bbc1464cSBarry Smith   DMSNES sdm;
2193bbc1464cSBarry Smith 
2194bbc1464cSBarry Smith   PetscFunctionBegin;
21959566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
21969566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
2197bbc1464cSBarry Smith   /*  A(x)*x - b(x) */
2198bbc1464cSBarry Smith   if (sdm->ops->computepfunction) {
2199792fecdfSBarry Smith     PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx));
22009566063dSJacob Faibussowitsch     PetscCall(VecScale(f, -1.0));
22010df40c35SBarry Smith     /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */
2202ef1023bdSBarry Smith     if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard));
2203792fecdfSBarry Smith     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx));
22049566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(snes->picard, x, f, f));
2205bbc1464cSBarry Smith   } else {
2206792fecdfSBarry Smith     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx));
22079566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->picard, x, f));
2208bbc1464cSBarry Smith   }
22093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2210bbc1464cSBarry Smith }
2211bbc1464cSBarry Smith 
2212d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx)
2213d71ae5a4SJacob Faibussowitsch {
2214e03ab78fSPeter Brune   DM     dm;
2215942e3340SBarry Smith   DMSNES sdm;
22166cab3a1bSJed Brown 
22178b0a5094SBarry Smith   PetscFunctionBegin;
22189566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
22199566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
22208b0a5094SBarry Smith   /*  A(x)*x - b(x) */
2221bbc1464cSBarry Smith   if (sdm->ops->computepfunction) {
2222792fecdfSBarry Smith     PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx));
22239566063dSJacob Faibussowitsch     PetscCall(VecScale(f, -1.0));
2224792fecdfSBarry Smith     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx));
22259566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f));
2226bbc1464cSBarry Smith   } else {
2227792fecdfSBarry Smith     PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx));
22289566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->jacobian_pre, x, f));
2229bbc1464cSBarry Smith   }
22303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22318b0a5094SBarry Smith }
22328b0a5094SBarry Smith 
2233d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx)
2234d71ae5a4SJacob Faibussowitsch {
22358b0a5094SBarry Smith   PetscFunctionBegin;
2236e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
2237bbc1464cSBarry Smith   /* must assembly if matrix-free to get the last SNES solution */
22389566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY));
22399566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY));
22403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22418b0a5094SBarry Smith }
22428b0a5094SBarry Smith 
22438b0a5094SBarry Smith /*@C
2244f6dfbefdSBarry Smith    SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization)
22458b0a5094SBarry Smith 
2246c3339decSBarry Smith    Logically Collective
22478b0a5094SBarry Smith 
22488b0a5094SBarry Smith    Input Parameters:
2249f6dfbefdSBarry Smith +  snes - the `SNES` context
22506b7fb656SBarry Smith .  r - vector to store function values, may be NULL
22516b7fb656SBarry Smith .  bp - function evaluation routine, may be NULL
22526b7fb656SBarry Smith .  Amat - matrix with which A(x) x - bp(x) - b is to be computed
2253e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
22546b7fb656SBarry Smith .  J  - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence
22556b7fb656SBarry Smith -  ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
22568b0a5094SBarry Smith 
22578b0a5094SBarry Smith    Notes:
22586b7fb656SBarry Smith     It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use
2259f450aa47SBarry Smith     an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton.
2260f450aa47SBarry Smith 
2261f6dfbefdSBarry Smith     One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both
22628b0a5094SBarry Smith 
22636b7fb656SBarry 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}
22646b7fb656SBarry 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.
22658b0a5094SBarry Smith 
22668b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
22678b0a5094SBarry Smith 
22680d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
22696b7fb656SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b
22708b0a5094SBarry Smith 
22718b0a5094SBarry Smith    There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some
22728b0a5094SBarry Smith    believe it is the iteration  A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative  reference that defines the Picard iteration
22738b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
22748b0a5094SBarry Smith 
2275f6dfbefdSBarry Smith    When used with -snes_mf_operator this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b and
2276f6dfbefdSBarry Smith     A(x^{n}) is used to build the preconditioner
22776b7fb656SBarry Smith 
22786b7fb656SBarry Smith    When used with -snes_fd this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method.
22796b7fb656SBarry Smith 
22806b7fb656SBarry Smith    When used with -snes_fd_coloring this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the
22816b7fb656SBarry Smith    the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct
2282f6dfbefdSBarry Smith    coloring. When using `DMDA` this may mean creating the matrix A with `DMCreateMatrix()` using a wider stencil than strictly needed for A or with a `DMDA_STENCIL_BOX`.
22836b7fb656SBarry Smith    See the commment in src/snes/tutorials/ex15.c.
2284bbc1464cSBarry Smith 
2285f450aa47SBarry Smith    Level: intermediate
22868b0a5094SBarry Smith 
2287f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction`
22888b0a5094SBarry Smith @*/
2289d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetPicard(SNES snes, Vec r, PetscErrorCode (*bp)(SNES, Vec, Vec, void *), Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx)
2290d71ae5a4SJacob Faibussowitsch {
2291e03ab78fSPeter Brune   DM dm;
2292e03ab78fSPeter Brune 
22938b0a5094SBarry Smith   PetscFunctionBegin;
22948b0a5094SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
22959566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
22969566063dSJacob Faibussowitsch   PetscCall(DMSNESSetPicard(dm, bp, J, ctx));
22979566063dSJacob Faibussowitsch   PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx));
22989566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx));
22999566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx));
23003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23018b0a5094SBarry Smith }
23028b0a5094SBarry Smith 
23037971a8bfSPeter Brune /*@C
23047971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
23057971a8bfSPeter Brune 
2306f6dfbefdSBarry Smith    Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet.
23077971a8bfSPeter Brune 
23087971a8bfSPeter Brune    Input Parameter:
2309f6dfbefdSBarry Smith .  snes - the `SNES` context
23107971a8bfSPeter Brune 
2311d8d19677SJose E. Roman    Output Parameters:
23120298fd71SBarry Smith +  r - the function (or NULL)
2313f6dfbefdSBarry Smith .  f - the function (or NULL); see `SNESFunction` for calling sequence details
2314e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2315e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2316f6dfbefdSBarry Smith .  J - the function for matrix evaluation (or NULL); see `SNESJacobianFunction` for calling sequence details
23170298fd71SBarry Smith -  ctx - the function context (or NULL)
23187971a8bfSPeter Brune 
23197971a8bfSPeter Brune    Level: advanced
23207971a8bfSPeter Brune 
2321f6dfbefdSBarry Smith .seealso: `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction`
23227971a8bfSPeter Brune @*/
2323d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetPicard(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx)
2324d71ae5a4SJacob Faibussowitsch {
23257971a8bfSPeter Brune   DM dm;
23267971a8bfSPeter Brune 
23277971a8bfSPeter Brune   PetscFunctionBegin;
23287971a8bfSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
23299566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, r, NULL, NULL));
23309566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL));
23319566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
23329566063dSJacob Faibussowitsch   PetscCall(DMSNESGetPicard(dm, f, J, ctx));
23333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23347971a8bfSPeter Brune }
23357971a8bfSPeter Brune 
2336d25893d9SBarry Smith /*@C
2337d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2338d25893d9SBarry Smith 
2339c3339decSBarry Smith    Logically Collective
2340d25893d9SBarry Smith 
2341d25893d9SBarry Smith    Input Parameters:
2342f6dfbefdSBarry Smith +  snes - the `SNES` context
2343d25893d9SBarry Smith .  func - function evaluation routine
2344d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
23450298fd71SBarry Smith          function evaluation routine (may be NULL)
2346d25893d9SBarry Smith 
2347d25893d9SBarry Smith    Calling sequence of func:
2348d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2349d25893d9SBarry Smith 
2350d25893d9SBarry Smith .  f - function vector
2351d25893d9SBarry Smith -  ctx - optional user-defined function context
2352d25893d9SBarry Smith 
2353d25893d9SBarry Smith    Level: intermediate
2354d25893d9SBarry Smith 
2355f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`
2356d25893d9SBarry Smith @*/
2357d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx)
2358d71ae5a4SJacob Faibussowitsch {
2359d25893d9SBarry Smith   PetscFunctionBegin;
2360d25893d9SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2361d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2362d25893d9SBarry Smith   if (ctx) snes->initialguessP = ctx;
23633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2364d25893d9SBarry Smith }
2365d25893d9SBarry Smith 
23661096aae1SMatthew Knepley /*@C
23671096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
23681096aae1SMatthew Knepley    it assumes a zero right hand side.
23691096aae1SMatthew Knepley 
2370c3339decSBarry Smith    Logically Collective
23711096aae1SMatthew Knepley 
23721096aae1SMatthew Knepley    Input Parameter:
2373f6dfbefdSBarry Smith .  snes - the `SNES` context
23741096aae1SMatthew Knepley 
23751096aae1SMatthew Knepley    Output Parameter:
23760298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
23771096aae1SMatthew Knepley 
23781096aae1SMatthew Knepley    Level: intermediate
23791096aae1SMatthew Knepley 
2380f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()`
23811096aae1SMatthew Knepley @*/
2382d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs)
2383d71ae5a4SJacob Faibussowitsch {
23841096aae1SMatthew Knepley   PetscFunctionBegin;
23850700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
23861096aae1SMatthew Knepley   PetscValidPointer(rhs, 2);
238785385478SLisandro Dalcin   *rhs = snes->vec_rhs;
23883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
23891096aae1SMatthew Knepley }
23901096aae1SMatthew Knepley 
23919b94acceSBarry Smith /*@
2392f6dfbefdSBarry Smith    SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`.
23939b94acceSBarry Smith 
2394c3339decSBarry Smith    Collective
2395c7afd0dbSLois Curfman McInnes 
23969b94acceSBarry Smith    Input Parameters:
2397f6dfbefdSBarry Smith +  snes - the `SNES` context
2398c7afd0dbSLois Curfman McInnes -  x - input vector
23999b94acceSBarry Smith 
24009b94acceSBarry Smith    Output Parameter:
2401f6dfbefdSBarry Smith .  y - function vector, as set by `SNESSetFunction()`
24029b94acceSBarry Smith 
2403f6dfbefdSBarry Smith    Note:
2404f6dfbefdSBarry Smith    `SNESComputeFunction()` is typically used within nonlinear solvers
2405bbc1464cSBarry Smith    implementations, so users would not generally call this routine themselves.
240636851e7fSLois Curfman McInnes 
240736851e7fSLois Curfman McInnes    Level: developer
240836851e7fSLois Curfman McInnes 
2409f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()`
24109b94acceSBarry Smith @*/
2411d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y)
2412d71ae5a4SJacob Faibussowitsch {
24136cab3a1bSJed Brown   DM     dm;
2414942e3340SBarry Smith   DMSNES sdm;
24159b94acceSBarry Smith 
24163a40ed3dSBarry Smith   PetscFunctionBegin;
24170700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
24180700a824SBarry Smith   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
24190700a824SBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2420c9780b6fSBarry Smith   PetscCheckSameComm(snes, 1, x, 2);
2421c9780b6fSBarry Smith   PetscCheckSameComm(snes, 1, y, 3);
2422e0f629ddSJacob Faibussowitsch   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2423184914b5SBarry Smith 
24249566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
24259566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
24260fdf79fbSJacob Faibussowitsch   PetscCheck(sdm->ops->computefunction || snes->vec_rhs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
242732f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
242848a46eb9SPierre Jolivet     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
24299566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(x));
24308ddeebeaSSteve Benbow     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
24318ddeebeaSSteve Benbow     snes->domainerror = PETSC_FALSE;
2432800f99ffSJeremy L Thompson     {
2433800f99ffSJeremy L Thompson       void *ctx;
2434800f99ffSJeremy L Thompson       PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *);
2435800f99ffSJeremy L Thompson       PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx));
2436800f99ffSJeremy L Thompson       PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx));
2437800f99ffSJeremy L Thompson     }
24389566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(x));
243948a46eb9SPierre Jolivet     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
24400fdf79fbSJacob Faibussowitsch   } else /* if (snes->vec_rhs) */ {
24419566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->jacobian, x, y));
24420fdf79fbSJacob Faibussowitsch   }
24431baa6e33SBarry Smith   if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs));
2444ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2445422a814eSBarry Smith   /*
2446422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2447422a814eSBarry Smith      propagate the value to all processes
2448422a814eSBarry Smith   */
24491baa6e33SBarry Smith   if (snes->domainerror) PetscCall(VecSetInf(y));
24503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
24519b94acceSBarry Smith }
24529b94acceSBarry Smith 
2453c79ef259SPeter Brune /*@
2454f6dfbefdSBarry Smith    SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`.
2455bbc1464cSBarry Smith 
2456c3339decSBarry Smith    Collective
2457bbc1464cSBarry Smith 
2458bbc1464cSBarry Smith    Input Parameters:
2459f6dfbefdSBarry Smith +  snes - the `SNES` context
2460bbc1464cSBarry Smith -  x - input vector
2461bbc1464cSBarry Smith 
2462bbc1464cSBarry Smith    Output Parameter:
2463f6dfbefdSBarry Smith .  y - function vector, as set by `SNESSetMFFunction()`
2464bbc1464cSBarry Smith 
2465bbc1464cSBarry Smith    Notes:
2466f6dfbefdSBarry Smith    `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()`
2467bbc1464cSBarry Smith    so users would not generally call this routine themselves.
2468bbc1464cSBarry Smith 
2469f6dfbefdSBarry Smith     Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()`
2470f6dfbefdSBarry Smith     while `SNESComputeFunction()` does. As such, this routine cannot be used with  `MatMFFDSetBase()` with a provided F function value even if it applies the
2471f6dfbefdSBarry Smith     same function as `SNESComputeFunction()` if a `SNESSolve()` right hand side vector is use because the two functions difference would include this right hand side function.
2472bbc1464cSBarry Smith 
2473bbc1464cSBarry Smith    Level: developer
2474bbc1464cSBarry Smith 
2475f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF`
2476bbc1464cSBarry Smith @*/
2477d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y)
2478d71ae5a4SJacob Faibussowitsch {
2479bbc1464cSBarry Smith   DM     dm;
2480bbc1464cSBarry Smith   DMSNES sdm;
2481bbc1464cSBarry Smith 
2482bbc1464cSBarry Smith   PetscFunctionBegin;
2483bbc1464cSBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2484bbc1464cSBarry Smith   PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
2485bbc1464cSBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
2486bbc1464cSBarry Smith   PetscCheckSameComm(snes, 1, x, 2);
2487bbc1464cSBarry Smith   PetscCheckSameComm(snes, 1, y, 3);
2488e0f629ddSJacob Faibussowitsch   PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE));
2489bbc1464cSBarry Smith 
24909566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
24919566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
24929566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0));
24939566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(x));
2494bbc1464cSBarry Smith   /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2495bbc1464cSBarry Smith   snes->domainerror = PETSC_FALSE;
2496792fecdfSBarry Smith   PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx));
24979566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(x));
24989566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0));
2499bbc1464cSBarry Smith   snes->nfuncs++;
2500bbc1464cSBarry Smith   /*
2501bbc1464cSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2502bbc1464cSBarry Smith      propagate the value to all processes
2503bbc1464cSBarry Smith   */
25041baa6e33SBarry Smith   if (snes->domainerror) PetscCall(VecSetInf(y));
25053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2506bbc1464cSBarry Smith }
2507bbc1464cSBarry Smith 
2508bbc1464cSBarry Smith /*@
2509f6dfbefdSBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  `SNESSetNGS()`.
2510c79ef259SPeter Brune 
2511c3339decSBarry Smith    Collective
2512c79ef259SPeter Brune 
2513c79ef259SPeter Brune    Input Parameters:
2514f6dfbefdSBarry Smith +  snes - the `SNES` context
2515c79ef259SPeter Brune .  x - input vector
2516c79ef259SPeter Brune -  b - rhs vector
2517c79ef259SPeter Brune 
2518c79ef259SPeter Brune    Output Parameter:
2519c79ef259SPeter Brune .  x - new solution vector
2520c79ef259SPeter Brune 
2521f6dfbefdSBarry Smith    Note:
2522f6dfbefdSBarry Smith    `SNESComputeNGS()` is typically used within composed nonlinear solver
2523c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2524c79ef259SPeter Brune    themselves.
2525c79ef259SPeter Brune 
2526c79ef259SPeter Brune    Level: developer
2527c79ef259SPeter Brune 
2528f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()`
2529c79ef259SPeter Brune @*/
2530d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x)
2531d71ae5a4SJacob Faibussowitsch {
25326cab3a1bSJed Brown   DM     dm;
2533942e3340SBarry Smith   DMSNES sdm;
2534646217ecSPeter Brune 
2535646217ecSPeter Brune   PetscFunctionBegin;
2536646217ecSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
2537064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
2538064a246eSJacob Faibussowitsch   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
2539064a246eSJacob Faibussowitsch   PetscCheckSameComm(snes, 1, x, 3);
2540064a246eSJacob Faibussowitsch   if (b) PetscCheckSameComm(snes, 1, b, 2);
2541e0f629ddSJacob Faibussowitsch   if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE));
25429566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0));
25439566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
25449566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
25450fdf79fbSJacob Faibussowitsch   PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
25469566063dSJacob Faibussowitsch   if (b) PetscCall(VecLockReadPush(b));
2547792fecdfSBarry Smith   PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx));
25489566063dSJacob Faibussowitsch   if (b) PetscCall(VecLockReadPop(b));
25499566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0));
25503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2551646217ecSPeter Brune }
2552646217ecSPeter Brune 
2553d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes)
2554d71ae5a4SJacob Faibussowitsch {
255512837594SBarry Smith   Mat               A, B, C, D, jacobian;
2556e885f1abSBarry Smith   Vec               x = snes->vec_sol, f = snes->vec_func;
2557e885f1abSBarry Smith   PetscReal         nrm, gnorm;
255881e7118cSBarry Smith   PetscReal         threshold = 1.e-5;
25590e276705SLisandro Dalcin   MatType           mattype;
2560e885f1abSBarry Smith   PetscInt          m, n, M, N;
2561e885f1abSBarry Smith   void             *functx;
25622cd624f9SStefano Zampini   PetscBool         complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose;
25633325ff46SBarry Smith   PetscViewer       viewer, mviewer;
2564e885f1abSBarry Smith   MPI_Comm          comm;
2565e885f1abSBarry Smith   PetscInt          tabs;
256612837594SBarry Smith   static PetscBool  directionsprinted = PETSC_FALSE;
25673325ff46SBarry Smith   PetscViewerFormat format;
2568e885f1abSBarry Smith 
2569e885f1abSBarry Smith   PetscFunctionBegin;
2570d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)snes);
25719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test));
25729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL));
25739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print));
257418d89885SKarl Rupp   if (!complete_print) {
25759566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL));
25769566063dSJacob Faibussowitsch     PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print));
257718d89885SKarl Rupp   }
257818d89885SKarl Rupp   /* for compatibility with PETSc 3.9 and older. */
25799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)"));
25809566063dSJacob 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));
2581d0609cedSBarry Smith   PetscOptionsEnd();
25823ba16761SJacob Faibussowitsch   if (!test) PetscFunctionReturn(PETSC_SUCCESS);
2583e885f1abSBarry Smith 
25849566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)snes, &comm));
25859566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm, &viewer));
25869566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
25879566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
25889566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian -------------\n"));
258912837594SBarry Smith   if (!complete_print && !directionsprinted) {
25909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n"));
25919566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n"));
259212837594SBarry Smith   }
259312837594SBarry Smith   if (!directionsprinted) {
25949566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
25959566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "    O(1.e-8), the hand-coded Jacobian is probably correct.\n"));
259612837594SBarry Smith     directionsprinted = PETSC_TRUE;
2597e885f1abSBarry Smith   }
25981baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format));
2599e885f1abSBarry Smith 
26009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg));
260112837594SBarry Smith   if (!flg) jacobian = snes->jacobian;
260212837594SBarry Smith   else jacobian = snes->jacobian_pre;
260312837594SBarry Smith 
2604a82339d0SMatthew G. Knepley   if (!x) {
26059566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(jacobian, &x, NULL));
2606a82339d0SMatthew G. Knepley   } else {
26079566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)x));
2608a82339d0SMatthew G. Knepley   }
2609a82339d0SMatthew G. Knepley   if (!f) {
26109566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &f));
2611a82339d0SMatthew G. Knepley   } else {
26129566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)f));
2613a82339d0SMatthew G. Knepley   }
2614a82339d0SMatthew G. Knepley   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
26159566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes, x, f));
26169566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&f));
26179566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose));
261812837594SBarry Smith   while (jacobian) {
26192cd624f9SStefano Zampini     Mat JT = NULL, Jsave = NULL;
26202cd624f9SStefano Zampini 
26212cd624f9SStefano Zampini     if (istranspose) {
26229566063dSJacob Faibussowitsch       PetscCall(MatCreateTranspose(jacobian, &JT));
26232cd624f9SStefano Zampini       Jsave    = jacobian;
26242cd624f9SStefano Zampini       jacobian = JT;
26252cd624f9SStefano Zampini     }
26269566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, ""));
262712837594SBarry Smith     if (flg) {
262812837594SBarry Smith       A = jacobian;
26299566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
263012837594SBarry Smith     } else {
26319566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(jacobian, MATAIJ, &A));
263212837594SBarry Smith     }
2633e885f1abSBarry Smith 
26349566063dSJacob Faibussowitsch     PetscCall(MatGetType(A, &mattype));
26359566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A, &M, &N));
26369566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A, &m, &n));
26379566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
26389566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, mattype));
26399566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, M, N));
26409566063dSJacob Faibussowitsch     PetscCall(MatSetBlockSizesFromMats(B, A, A));
26419566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
26429566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
2643e885f1abSBarry Smith 
26449566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes, NULL, NULL, &functx));
26459566063dSJacob Faibussowitsch     PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx));
264612837594SBarry Smith 
26479566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D));
26489566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN));
26499566063dSJacob Faibussowitsch     PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm));
26509566063dSJacob Faibussowitsch     PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm));
26519566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
265212837594SBarry Smith     if (!gnorm) gnorm = 1; /* just in case */
26539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm));
265412837594SBarry Smith 
2655e885f1abSBarry Smith     if (complete_print) {
26569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded Jacobian ----------\n"));
26579566063dSJacob Faibussowitsch       PetscCall(MatView(A, mviewer));
26589566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Finite difference Jacobian ----------\n"));
26599566063dSJacob Faibussowitsch       PetscCall(MatView(B, mviewer));
2660e885f1abSBarry Smith     }
2661e885f1abSBarry Smith 
2662df10fb39SFande Kong     if (threshold_print || complete_print) {
2663e885f1abSBarry Smith       PetscInt           Istart, Iend, *ccols, bncols, cncols, j, row;
2664e885f1abSBarry Smith       PetscScalar       *cvals;
2665e885f1abSBarry Smith       const PetscInt    *bcols;
2666e885f1abSBarry Smith       const PetscScalar *bvals;
2667e885f1abSBarry Smith 
26689566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C));
26699566063dSJacob Faibussowitsch       PetscCall(MatSetType(C, mattype));
26709566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C, m, n, M, N));
26719566063dSJacob Faibussowitsch       PetscCall(MatSetBlockSizesFromMats(C, A, A));
26729566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
26739566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE));
26740e276705SLisandro Dalcin 
26759566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN));
26769566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B, &Istart, &Iend));
2677e885f1abSBarry Smith 
2678e885f1abSBarry Smith       for (row = Istart; row < Iend; row++) {
26799566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals));
26809566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals));
2681e885f1abSBarry Smith         for (j = 0, cncols = 0; j < bncols; j++) {
268223a52b1dSBarry Smith           if (PetscAbsScalar(bvals[j]) > threshold) {
2683e885f1abSBarry Smith             ccols[cncols] = bcols[j];
2684e885f1abSBarry Smith             cvals[cncols] = bvals[j];
2685e885f1abSBarry Smith             cncols += 1;
2686e885f1abSBarry Smith           }
2687e885f1abSBarry Smith         }
268848a46eb9SPierre Jolivet         if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES));
26899566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals));
26909566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols, cvals));
2691e885f1abSBarry Smith       }
26929566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
26939566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
26949566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold));
26959566063dSJacob Faibussowitsch       PetscCall(MatView(C, complete_print ? mviewer : viewer));
26969566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
2697e885f1abSBarry Smith     }
26989566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
26999566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
27009566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&JT));
27012cd624f9SStefano Zampini     if (Jsave) jacobian = Jsave;
270212837594SBarry Smith     if (jacobian != snes->jacobian_pre) {
270312837594SBarry Smith       jacobian = snes->jacobian_pre;
27049566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "  ---------- Testing Jacobian for preconditioner -------------\n"));
27059371c9d4SSatish Balay     } else jacobian = NULL;
270612837594SBarry Smith   }
27079566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&x));
27081baa6e33SBarry Smith   if (complete_print) PetscCall(PetscViewerPopFormat(mviewer));
27099566063dSJacob Faibussowitsch   if (mviewer) PetscCall(PetscViewerDestroy(&mviewer));
27109566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, tabs));
27113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2712e885f1abSBarry Smith }
2713e885f1abSBarry Smith 
271462fef451SLois Curfman McInnes /*@
2715f6dfbefdSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`.
271662fef451SLois Curfman McInnes 
2717c3339decSBarry Smith    Collective
2718c7afd0dbSLois Curfman McInnes 
271962fef451SLois Curfman McInnes    Input Parameters:
2720f6dfbefdSBarry Smith +  snes - the `SNES` context
2721c7afd0dbSLois Curfman McInnes -  x - input vector
272262fef451SLois Curfman McInnes 
272362fef451SLois Curfman McInnes    Output Parameters:
2724c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2725f6dfbefdSBarry Smith -  B - optional matrix for building the preconditioner
2726fee21e36SBarry Smith 
2727e35cf81dSBarry Smith   Options Database Keys:
272867b8a455SSatish Balay +    -snes_lag_preconditioner <lag> - how often to rebuild preconditioner
272967b8a455SSatish Balay .    -snes_lag_jacobian <lag> - how often to rebuild Jacobian
2730455a5933SJed 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.
2731455a5933SJed 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
2732693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2733693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2734693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
27354c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
273694d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2737a5b23f4aSJose E. Roman .    -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences
2738c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2739c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2740c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2741a5b23f4aSJose E. Roman .    -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences
2742a5b23f4aSJose E. Roman -    -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences
2743c01495d3SJed Brown 
2744f6dfbefdSBarry Smith    Note:
274562fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
274662fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
274762fef451SLois Curfman McInnes 
2748f6dfbefdSBarry Smith    Developer Note:
274995452b02SPatrick 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
2750e885f1abSBarry Smith       for with the SNESType of test that has been removed.
2751e885f1abSBarry Smith 
275236851e7fSLois Curfman McInnes    Level: developer
275336851e7fSLois Curfman McInnes 
2754db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
275562fef451SLois Curfman McInnes @*/
2756d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B)
2757d71ae5a4SJacob Faibussowitsch {
2758ace3abfcSBarry Smith   PetscBool flag;
27596cab3a1bSJed Brown   DM        dm;
2760942e3340SBarry Smith   DMSNES    sdm;
2761e0e3a89bSBarry Smith   KSP       ksp;
27623a40ed3dSBarry Smith 
27633a40ed3dSBarry Smith   PetscFunctionBegin;
27640700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
27650700a824SBarry Smith   PetscValidHeaderSpecific(X, VEC_CLASSID, 2);
2766c9780b6fSBarry Smith   PetscCheckSameComm(snes, 1, X, 2);
2767e0f629ddSJacob Faibussowitsch   PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE));
27689566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
27699566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
27703232da50SPeter Brune 
2771ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2772fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2773fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2774f5af7f23SKarl Rupp 
27759566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n"));
2776fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
27779566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n"));
27789566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2779ebd3b9afSBarry Smith     if (flag) {
27809566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
27819566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2782ebd3b9afSBarry Smith     }
27833ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
278437ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
278563a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter));
27869566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag));
2787ebd3b9afSBarry Smith     if (flag) {
27889566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
27899566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
2790ebd3b9afSBarry Smith     }
27913ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
2792e35cf81dSBarry Smith   }
2793efd4aadfSBarry Smith   if (snes->npc && snes->npcside == PC_LEFT) {
27949566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
27959566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
27963ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
2797d728fb7dSPeter Brune   }
2798e35cf81dSBarry Smith 
27999566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B));
28009566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2801800f99ffSJeremy L Thompson   {
2802800f99ffSJeremy L Thompson     void *ctx;
2803800f99ffSJeremy L Thompson     PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *);
2804800f99ffSJeremy L Thompson     PetscCall(DMSNESGetJacobian(dm, &J, &ctx));
2805800f99ffSJeremy L Thompson     PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx));
2806800f99ffSJeremy L Thompson   }
28079566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
28089566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B));
280928d58a37SPierre Jolivet 
281028d58a37SPierre Jolivet   /* attach latest linearization point to the preconditioning matrix */
28119566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X));
2812a8054027SBarry Smith 
2813e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
28149566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
28153b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
28169566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n"));
28179566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
28183b4f5425SBarry Smith     snes->lagpreconditioner = -1;
28193b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
28209566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n"));
28219566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
282237ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
282363a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter));
28249566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE));
2825d1e9a80fSBarry Smith   } else {
28269566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n"));
28279566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE));
2828a8054027SBarry Smith   }
2829a8054027SBarry Smith 
28309566063dSJacob Faibussowitsch   PetscCall(SNESTestJacobian(snes));
28316d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
283294ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
283394ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2834693365a8SJed Brown   {
2835693365a8SJed Brown     PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE;
28369566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag));
28379566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw));
28389566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour));
28399566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator));
2840693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
28410298fd71SBarry Smith       Mat         Bexp_mine = NULL, Bexp, FDexp;
2842693365a8SJed Brown       PetscViewer vdraw, vstdout;
28436b3a5b13SJed Brown       PetscBool   flg;
2844693365a8SJed Brown       if (flag_operator) {
28459566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine));
2846693365a8SJed Brown         Bexp = Bexp_mine;
2847693365a8SJed Brown       } else {
2848693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
28499566063dSJacob Faibussowitsch         PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, ""));
285094ab13aaSBarry Smith         if (flg) Bexp = B;
2851693365a8SJed Brown         else {
2852693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
28539566063dSJacob Faibussowitsch           PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine));
2854693365a8SJed Brown           Bexp = Bexp_mine;
2855693365a8SJed Brown         }
2856693365a8SJed Brown       }
28579566063dSJacob Faibussowitsch       PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp));
28589566063dSJacob Faibussowitsch       PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL));
28599566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
2860693365a8SJed Brown       if (flag_draw || flag_contour) {
28619566063dSJacob Faibussowitsch         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
28629566063dSJacob Faibussowitsch         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
28630298fd71SBarry Smith       } else vdraw = NULL;
28649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian"));
28659566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(Bexp, vstdout));
28669566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(Bexp, vdraw));
28679566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n"));
28689566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(FDexp, vstdout));
28699566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(FDexp, vdraw));
28709566063dSJacob Faibussowitsch       PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN));
28719566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n"));
28729566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(FDexp, vstdout));
2873693365a8SJed Brown       if (vdraw) { /* Always use contour for the difference */
28749566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
28759566063dSJacob Faibussowitsch         PetscCall(MatView(FDexp, vdraw));
28769566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(vdraw));
2877693365a8SJed Brown       }
28789566063dSJacob Faibussowitsch       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
28799566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&vdraw));
28809566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bexp_mine));
28819566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&FDexp));
2882693365a8SJed Brown     }
2883693365a8SJed Brown   }
28844c30e9fbSJed Brown   {
28856719d8e4SJed Brown     PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE;
28866719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON;
28879566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag));
28889566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display));
28899566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw));
28909566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour));
28919566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold));
289227b0f280SBarry Smith     if (flag_threshold) {
28939566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL));
28949566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL));
289527b0f280SBarry Smith     }
28966719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
28974c30e9fbSJed Brown       Mat           Bfd;
28984c30e9fbSJed Brown       PetscViewer   vdraw, vstdout;
2899335efc43SPeter Brune       MatColoring   coloring;
29004c30e9fbSJed Brown       ISColoring    iscoloring;
29014c30e9fbSJed Brown       MatFDColoring matfdcoloring;
29024c30e9fbSJed Brown       PetscErrorCode (*func)(SNES, Vec, Vec, void *);
29034c30e9fbSJed Brown       void     *funcctx;
29046719d8e4SJed Brown       PetscReal norm1, norm2, normmax;
29054c30e9fbSJed Brown 
29069566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd));
29079566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(Bfd, &coloring));
29089566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(coloring, MATCOLORINGSL));
29099566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(coloring));
29109566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(coloring, &iscoloring));
29119566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&coloring));
29129566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring));
29139566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
29149566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring));
29159566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
29164c30e9fbSJed Brown 
29174c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
29189566063dSJacob Faibussowitsch       PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx));
29199566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx));
29209566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix));
29219566063dSJacob Faibussowitsch       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_"));
29229566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
29239566063dSJacob Faibussowitsch       PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes));
29249566063dSJacob Faibussowitsch       PetscCall(MatFDColoringDestroy(&matfdcoloring));
29254c30e9fbSJed Brown 
29269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout));
29274c30e9fbSJed Brown       if (flag_draw || flag_contour) {
29289566063dSJacob Faibussowitsch         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw));
29299566063dSJacob Faibussowitsch         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
29300298fd71SBarry Smith       } else vdraw = NULL;
29319566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n"));
29329566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(B, vstdout));
29339566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(B, vdraw));
29349566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n"));
29359566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(Bfd, vstdout));
29369566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(Bfd, vdraw));
29379566063dSJacob Faibussowitsch       PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN));
29389566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd, NORM_1, &norm1));
29399566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2));
29409566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd, NORM_MAX, &normmax));
29419566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax));
29429566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(Bfd, vstdout));
29434c30e9fbSJed Brown       if (vdraw) { /* Always use contour for the difference */
29449566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR));
29459566063dSJacob Faibussowitsch         PetscCall(MatView(Bfd, vdraw));
29469566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(vdraw));
29474c30e9fbSJed Brown       }
29489566063dSJacob Faibussowitsch       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
29496719d8e4SJed Brown 
29506719d8e4SJed Brown       if (flag_threshold) {
29516719d8e4SJed Brown         PetscInt bs, rstart, rend, i;
29529566063dSJacob Faibussowitsch         PetscCall(MatGetBlockSize(B, &bs));
29539566063dSJacob Faibussowitsch         PetscCall(MatGetOwnershipRange(B, &rstart, &rend));
29546719d8e4SJed Brown         for (i = rstart; i < rend; i++) {
29556719d8e4SJed Brown           const PetscScalar *ba, *ca;
29566719d8e4SJed Brown           const PetscInt    *bj, *cj;
29576719d8e4SJed Brown           PetscInt           bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1;
29586719d8e4SJed Brown           PetscReal          maxentry = 0, maxdiff = 0, maxrdiff = 0;
29599566063dSJacob Faibussowitsch           PetscCall(MatGetRow(B, i, &bn, &bj, &ba));
29609566063dSJacob Faibussowitsch           PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca));
29615f80ce2aSJacob Faibussowitsch           PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
29626719d8e4SJed Brown           for (j = 0; j < bn; j++) {
29636719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
29646719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
29656719d8e4SJed Brown               maxentrycol = bj[j];
29666719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
29676719d8e4SJed Brown             }
29686719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
29696719d8e4SJed Brown               maxdiffcol = bj[j];
29706719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
29716719d8e4SJed Brown             }
29726719d8e4SJed Brown             if (rdiff > maxrdiff) {
29736719d8e4SJed Brown               maxrdiffcol = bj[j];
29746719d8e4SJed Brown               maxrdiff    = rdiff;
29756719d8e4SJed Brown             }
29766719d8e4SJed Brown           }
29776719d8e4SJed Brown           if (maxrdiff > 1) {
297863a3b9bcSJacob 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));
29796719d8e4SJed Brown             for (j = 0; j < bn; j++) {
29806719d8e4SJed Brown               PetscReal rdiff;
29816719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j]));
298248a46eb9SPierre Jolivet               if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j])));
29836719d8e4SJed Brown             }
298463a3b9bcSJacob Faibussowitsch             PetscCall(PetscViewerASCIIPrintf(vstdout, "\n"));
29856719d8e4SJed Brown           }
29869566063dSJacob Faibussowitsch           PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba));
29879566063dSJacob Faibussowitsch           PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca));
29886719d8e4SJed Brown         }
29896719d8e4SJed Brown       }
29909566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&vdraw));
29919566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bfd));
29924c30e9fbSJed Brown     }
29934c30e9fbSJed Brown   }
29943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29959b94acceSBarry Smith }
29969b94acceSBarry Smith 
2997bf388a1fSBarry Smith /*MC
2998f6dfbefdSBarry Smith     SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES`
2999bf388a1fSBarry Smith 
3000bf388a1fSBarry Smith      Synopsis:
3001411c0326SBarry Smith      #include "petscsnes.h"
3002411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
3003bf388a1fSBarry Smith 
3004c3339decSBarry Smith      Collective
30051843f636SBarry Smith 
30061843f636SBarry Smith     Input Parameters:
30071843f636SBarry Smith +  x - input vector, the Jacobian is to be computed at this value
3008bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
3009bf388a1fSBarry Smith 
30101843f636SBarry Smith     Output Parameters:
30111843f636SBarry Smith +  Amat - the matrix that defines the (approximate) Jacobian
30121843f636SBarry Smith -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
30131843f636SBarry Smith 
3014878cb397SSatish Balay    Level: intermediate
3015878cb397SSatish Balay 
3016f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()`
3017bf388a1fSBarry Smith M*/
3018bf388a1fSBarry Smith 
30199b94acceSBarry Smith /*@C
30209b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
3021044dda88SLois Curfman McInnes    location to store the matrix.
30229b94acceSBarry Smith 
3023c3339decSBarry Smith    Logically Collective
3024c7afd0dbSLois Curfman McInnes 
30259b94acceSBarry Smith    Input Parameters:
3026f6dfbefdSBarry Smith +  snes - the `SNES` context
3027e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
3028e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
3029f6dfbefdSBarry Smith .  J - Jacobian evaluation routine (if NULL then `SNES` retains any previously set value), see `SNESJacobianFunction` for details
3030c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
30310298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
30329b94acceSBarry Smith 
30339b94acceSBarry Smith    Notes:
3034f6dfbefdSBarry Smith    If the Amat matrix and Pmat matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on
303516913363SBarry Smith    each matrix.
303616913363SBarry Smith 
3037f6dfbefdSBarry Smith    If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
3038895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
3039895c21f2SBarry Smith 
3040f6dfbefdSBarry Smith    If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the ctx argument
3041f6dfbefdSBarry Smith    must be a `MatFDColoring`.
3042a8a26c1eSJed Brown 
3043c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
3044f6dfbefdSBarry Smith    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()`
3045c3cc8fd1SJed Brown 
304636851e7fSLois Curfman McInnes    Level: beginner
304736851e7fSLois Curfman McInnes 
3048f6dfbefdSBarry Smith .seealso: `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`,
3049db781477SPatrick Sanan           `SNESSetPicard()`, `SNESJacobianFunction`
30509b94acceSBarry Smith @*/
3051d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx)
3052d71ae5a4SJacob Faibussowitsch {
30536cab3a1bSJed Brown   DM dm;
30543a7fca6bSBarry Smith 
30553a40ed3dSBarry Smith   PetscFunctionBegin;
30560700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3057e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
3058e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
3059e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes, 1, Amat, 2);
3060e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3);
30619566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
30629566063dSJacob Faibussowitsch   PetscCall(DMSNESSetJacobian(dm, J, ctx));
3063e5d3d808SBarry Smith   if (Amat) {
30649566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
30659566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&snes->jacobian));
3066f5af7f23SKarl Rupp 
3067e5d3d808SBarry Smith     snes->jacobian = Amat;
30683a7fca6bSBarry Smith   }
3069e5d3d808SBarry Smith   if (Pmat) {
30709566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
30719566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&snes->jacobian_pre));
3072f5af7f23SKarl Rupp 
3073e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
30743a7fca6bSBarry Smith   }
30753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30769b94acceSBarry Smith }
307762fef451SLois Curfman McInnes 
3078c2aafc4cSSatish Balay /*@C
3079b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
3080b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
3081b4fd4287SBarry Smith 
3082f6dfbefdSBarry Smith    Not Collective, but `Mat` object will be parallel if `SNES` object is
3083c7afd0dbSLois Curfman McInnes 
3084b4fd4287SBarry Smith    Input Parameter:
3085b4fd4287SBarry Smith .  snes - the nonlinear solver context
3086b4fd4287SBarry Smith 
3087b4fd4287SBarry Smith    Output Parameters:
3088e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
3089e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
3090411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
30910298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
3092fee21e36SBarry Smith 
309336851e7fSLois Curfman McInnes    Level: advanced
309436851e7fSLois Curfman McInnes 
3095f6dfbefdSBarry Smith .seealso: `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()`
3096b4fd4287SBarry Smith @*/
3097d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx)
3098d71ae5a4SJacob Faibussowitsch {
30996cab3a1bSJed Brown   DM dm;
31006cab3a1bSJed Brown 
31013a40ed3dSBarry Smith   PetscFunctionBegin;
31020700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3103e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
3104e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
31059566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
3106800f99ffSJeremy L Thompson   PetscCall(DMSNESGetJacobian(dm, J, ctx));
31073ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3108b4fd4287SBarry Smith }
3109b4fd4287SBarry Smith 
3110d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
3111d71ae5a4SJacob Faibussowitsch {
311258b371f3SBarry Smith   DM     dm;
311358b371f3SBarry Smith   DMSNES sdm;
311458b371f3SBarry Smith 
311558b371f3SBarry Smith   PetscFunctionBegin;
31169566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
31179566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
311858b371f3SBarry Smith   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
311958b371f3SBarry Smith     DM        dm;
312058b371f3SBarry Smith     PetscBool isdense, ismf;
312158b371f3SBarry Smith 
31229566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
31239566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL));
31249566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL));
312558b371f3SBarry Smith     if (isdense) {
31269566063dSJacob Faibussowitsch       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL));
312758b371f3SBarry Smith     } else if (!ismf) {
31289566063dSJacob Faibussowitsch       PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL));
312958b371f3SBarry Smith     }
313058b371f3SBarry Smith   }
31313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
313258b371f3SBarry Smith }
313358b371f3SBarry Smith 
31349b94acceSBarry Smith /*@
31359b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
3136272ac6f2SLois Curfman McInnes    of a nonlinear solver.
31379b94acceSBarry Smith 
3138c3339decSBarry Smith    Collective
3139fee21e36SBarry Smith 
3140c7afd0dbSLois Curfman McInnes    Input Parameters:
3141f6dfbefdSBarry Smith .  snes - the `SNES` context
3142c7afd0dbSLois Curfman McInnes 
3143f6dfbefdSBarry Smith    Note:
3144f6dfbefdSBarry Smith    For basic use of the `SNES` solvers the user need not explicitly call
3145f6dfbefdSBarry Smith    `SNESSetUp()`, since these actions will automatically occur during
3146f6dfbefdSBarry Smith    the call to `SNESSolve()`.  However, if one wishes to control this
3147f6dfbefdSBarry Smith    phase separately, `SNESSetUp()` should be called after `SNESCreate()`
3148f6dfbefdSBarry Smith    and optional routines of the form SNESSetXXX(), but before `SNESSolve()`.
3149272ac6f2SLois Curfman McInnes 
315036851e7fSLois Curfman McInnes    Level: advanced
315136851e7fSLois Curfman McInnes 
3152f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()`
31539b94acceSBarry Smith @*/
3154d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes)
3155d71ae5a4SJacob Faibussowitsch {
31566cab3a1bSJed Brown   DM             dm;
3157942e3340SBarry Smith   DMSNES         sdm;
3158c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
31596e2a1849SPeter Brune   void          *lsprectx, *lspostctx;
31609b5c1c08SStefano Zampini   PetscBool      mf_operator, mf;
31619b5c1c08SStefano Zampini   Vec            f, fpc;
31629b5c1c08SStefano Zampini   void          *funcctx;
31639b5c1c08SStefano Zampini   void          *jacctx, *appctx;
31649b5c1c08SStefano Zampini   Mat            j, jpre;
31656b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *);
31666b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *);
31676e2a1849SPeter Brune   PetscErrorCode (*func)(SNES, Vec, Vec, void *);
3168d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *);
31693a40ed3dSBarry Smith 
31703a40ed3dSBarry Smith   PetscFunctionBegin;
31710700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
31723ba16761SJacob Faibussowitsch   if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
3173*fc8bc0e3SRichard Tran Mills   PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0));
31749b94acceSBarry Smith 
317548a46eb9SPierre Jolivet   if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS));
317685385478SLisandro Dalcin 
31779566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL));
317858c9b817SLisandro Dalcin 
31799566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
31809566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm, &sdm));
31819566063dSJacob Faibussowitsch   PetscCall(SNESSetDefaultComputeJacobian(snes));
318258b371f3SBarry Smith 
318348a46eb9SPierre Jolivet   if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func));
3184efd51863SBarry Smith 
318548a46eb9SPierre Jolivet   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
3186b710008aSBarry Smith 
3187d8d34be6SBarry Smith   if (snes->linesearch) {
31889566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
31899566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction));
3190d8d34be6SBarry Smith   }
31919e764e56SPeter Brune 
31929b5c1c08SStefano Zampini   PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf));
3193b552625fSStefano Zampini   if (snes->npc && snes->npcside == PC_LEFT) {
3194172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
3195172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
3196172a4300SPeter Brune   }
3197d8f46077SPeter Brune 
3198efd4aadfSBarry Smith   if (snes->npc) {
31996e2a1849SPeter Brune     /* copy the DM over */
32009566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
32019566063dSJacob Faibussowitsch     PetscCall(SNESSetDM(snes->npc, dm));
32026e2a1849SPeter Brune 
32039566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes, &f, &func, &funcctx));
32049566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(f, &fpc));
32059566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx));
32069566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx));
32079566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx));
32089566063dSJacob Faibussowitsch     PetscCall(SNESGetApplicationContext(snes, &appctx));
32099566063dSJacob Faibussowitsch     PetscCall(SNESSetApplicationContext(snes->npc, appctx));
32109b5c1c08SStefano Zampini     PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf));
32119566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&fpc));
32126e2a1849SPeter Brune 
32136e2a1849SPeter Brune     /* copy the function pointers over */
32149566063dSJacob Faibussowitsch     PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc));
32156e2a1849SPeter Brune 
32166e2a1849SPeter Brune     /* default to 1 iteration */
32179566063dSJacob Faibussowitsch     PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs));
3218efd4aadfSBarry Smith     if (snes->npcside == PC_RIGHT) {
32199566063dSJacob Faibussowitsch       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY));
3220a9936a0cSPeter Brune     } else {
32219566063dSJacob Faibussowitsch       PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE));
3222a9936a0cSPeter Brune     }
32239566063dSJacob Faibussowitsch     PetscCall(SNESSetFromOptions(snes->npc));
32246e2a1849SPeter Brune 
32256e2a1849SPeter Brune     /* copy the line search context over */
3226d8d34be6SBarry Smith     if (snes->linesearch && snes->npc->linesearch) {
32279566063dSJacob Faibussowitsch       PetscCall(SNESGetLineSearch(snes, &linesearch));
32289566063dSJacob Faibussowitsch       PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch));
32299566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx));
32309566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx));
32319566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx));
32329566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx));
32339566063dSJacob Faibussowitsch       PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch));
32346e2a1849SPeter Brune     }
3235d8d34be6SBarry Smith   }
32361baa6e33SBarry Smith   if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version));
323748a46eb9SPierre Jolivet   if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user));
32386e2a1849SPeter Brune 
323937ec4e1aSPeter Brune   snes->jac_iter = 0;
324037ec4e1aSPeter Brune   snes->pre_iter = 0;
324137ec4e1aSPeter Brune 
3242dbbe0bcdSBarry Smith   PetscTryTypeMethod(snes, setup);
324358c9b817SLisandro Dalcin 
32449566063dSJacob Faibussowitsch   PetscCall(SNESSetDefaultComputeJacobian(snes));
324558b371f3SBarry Smith 
3246b552625fSStefano Zampini   if (snes->npc && snes->npcside == PC_LEFT) {
32476c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3248d8d34be6SBarry Smith       if (snes->linesearch) {
32499566063dSJacob Faibussowitsch         PetscCall(SNESGetLineSearch(snes, &linesearch));
32509566063dSJacob Faibussowitsch         PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC));
32516c67d002SPeter Brune       }
32526c67d002SPeter Brune     }
3253d8d34be6SBarry Smith   }
3254*fc8bc0e3SRichard Tran Mills   PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0));
32557aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
32563ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
32579b94acceSBarry Smith }
32589b94acceSBarry Smith 
325937596af1SLisandro Dalcin /*@
3260f6dfbefdSBarry Smith    SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s
326137596af1SLisandro Dalcin 
3262c3339decSBarry Smith    Collective
326337596af1SLisandro Dalcin 
326437596af1SLisandro Dalcin    Input Parameter:
3265f6dfbefdSBarry Smith .  snes - iterative context obtained from `SNESCreate()`
326637596af1SLisandro Dalcin 
3267d25893d9SBarry Smith    Level: intermediate
3268d25893d9SBarry Smith 
326995452b02SPatrick Sanan    Notes:
3270f6dfbefdSBarry Smith    Call this if you wish to reuse a `SNES` but with different size vectors
327137596af1SLisandro Dalcin 
3272f6dfbefdSBarry Smith    Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()`
3273f6dfbefdSBarry Smith 
3274f6dfbefdSBarry Smith .seealso: `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()`
327537596af1SLisandro Dalcin @*/
3276d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes)
3277d71ae5a4SJacob Faibussowitsch {
327837596af1SLisandro Dalcin   PetscFunctionBegin;
327937596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3280d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
32819566063dSJacob Faibussowitsch     PetscCall((*snes->ops->userdestroy)((void **)&snes->user));
32820298fd71SBarry Smith     snes->user = NULL;
3283d25893d9SBarry Smith   }
32841baa6e33SBarry Smith   if (snes->npc) PetscCall(SNESReset(snes->npc));
32858a23116dSBarry Smith 
3286dbbe0bcdSBarry Smith   PetscTryTypeMethod(snes, reset);
32871baa6e33SBarry Smith   if (snes->ksp) PetscCall(KSPReset(snes->ksp));
32889e764e56SPeter Brune 
32891baa6e33SBarry Smith   if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch));
32909e764e56SPeter Brune 
32919566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_rhs));
32929566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol));
32939566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol_update));
32949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_func));
32959566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->jacobian));
32969566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->jacobian_pre));
32979566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->picard));
32989566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(snes->nwork, &snes->work));
32999566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork));
3300f5af7f23SKarl Rupp 
330140fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
330240fdac6aSLawrence Mitchell 
330337596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
330437596af1SLisandro Dalcin   snes->setupcalled          = PETSC_FALSE;
33053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
330637596af1SLisandro Dalcin }
330737596af1SLisandro Dalcin 
330852baeb72SSatish Balay /*@
3309f6dfbefdSBarry Smith    SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object.
3310c4421ceaSFande Kong 
3311c3339decSBarry Smith    Collective
3312c4421ceaSFande Kong 
3313c4421ceaSFande Kong    Input Parameter:
3314f6dfbefdSBarry Smith .  snes - iterative context obtained from `SNESCreate()`
3315c4421ceaSFande Kong 
3316c4421ceaSFande Kong    Level: intermediate
3317c4421ceaSFande Kong 
3318f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()`
3319c4421ceaSFande Kong @*/
3320d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes)
3321d71ae5a4SJacob Faibussowitsch {
3322c4421ceaSFande Kong   PetscInt i;
3323c4421ceaSFande Kong 
3324c4421ceaSFande Kong   PetscFunctionBegin;
3325c4421ceaSFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3326c4421ceaSFande Kong   for (i = 0; i < snes->numberreasonviews; i++) {
332748a46eb9SPierre Jolivet     if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]));
3328c4421ceaSFande Kong   }
3329c4421ceaSFande Kong   snes->numberreasonviews = 0;
33303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3331c4421ceaSFande Kong }
3332c4421ceaSFande Kong 
33331fb7b255SJunchao Zhang /*@C
33349b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
3335f6dfbefdSBarry Smith    with `SNESCreate()`.
33369b94acceSBarry Smith 
3337c3339decSBarry Smith    Collective
3338c7afd0dbSLois Curfman McInnes 
33399b94acceSBarry Smith    Input Parameter:
3340f6dfbefdSBarry Smith .  snes - the `SNES` context
33419b94acceSBarry Smith 
334236851e7fSLois Curfman McInnes    Level: beginner
334336851e7fSLois Curfman McInnes 
3344f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()`
33459b94acceSBarry Smith @*/
3346d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes)
3347d71ae5a4SJacob Faibussowitsch {
33483a40ed3dSBarry Smith   PetscFunctionBegin;
33493ba16761SJacob Faibussowitsch   if (!*snes) PetscFunctionReturn(PETSC_SUCCESS);
33506bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1);
33519371c9d4SSatish Balay   if (--((PetscObject)(*snes))->refct > 0) {
33529371c9d4SSatish Balay     *snes = NULL;
33533ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
33549371c9d4SSatish Balay   }
3355d4bb536fSBarry Smith 
33569566063dSJacob Faibussowitsch   PetscCall(SNESReset((*snes)));
33579566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*snes)->npc));
33586b8b9a38SLisandro Dalcin 
3359e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
33609566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes));
3361dbbe0bcdSBarry Smith   PetscTryTypeMethod((*snes), destroy);
33626d4c513bSLisandro Dalcin 
33639566063dSJacob Faibussowitsch   if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes));
33649566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*snes)->dm));
33659566063dSJacob Faibussowitsch   PetscCall(KSPDestroy(&(*snes)->ksp));
33669566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch));
33676b8b9a38SLisandro Dalcin 
33689566063dSJacob Faibussowitsch   PetscCall(PetscFree((*snes)->kspconvctx));
336948a46eb9SPierre Jolivet   if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP));
337048a46eb9SPierre Jolivet   if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its));
33719566063dSJacob Faibussowitsch   PetscCall(SNESMonitorCancel((*snes)));
33729566063dSJacob Faibussowitsch   PetscCall(SNESConvergedReasonViewCancel((*snes)));
33739566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(snes));
33743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33759b94acceSBarry Smith }
33769b94acceSBarry Smith 
33779b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
33789b94acceSBarry Smith 
3379a8054027SBarry Smith /*@
3380a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3381a8054027SBarry Smith 
3382c3339decSBarry Smith    Logically Collective
3383a8054027SBarry Smith 
3384a8054027SBarry Smith    Input Parameters:
3385f6dfbefdSBarry Smith +  snes - the `SNES` context
3386d8e291bfSBarry Smith -  lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
33873b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3388a8054027SBarry Smith 
3389a8054027SBarry Smith    Options Database Keys:
33903d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
33913d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
33923d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
33933d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3394a8054027SBarry Smith 
3395a8054027SBarry Smith    Notes:
3396a8054027SBarry Smith    The default is 1
3397f6dfbefdSBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called
3398d8e291bfSBarry Smith 
3399f6dfbefdSBarry Smith    `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves.
3400a8054027SBarry Smith 
3401a8054027SBarry Smith    Level: intermediate
3402a8054027SBarry Smith 
3403db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`,
3404f6dfbefdSBarry Smith           `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()`
3405a8054027SBarry Smith @*/
3406d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag)
3407d71ae5a4SJacob Faibussowitsch {
3408a8054027SBarry Smith   PetscFunctionBegin;
34090700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
34105f80ce2aSJacob Faibussowitsch   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
34115f80ce2aSJacob Faibussowitsch   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3412c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, lag, 2);
3413a8054027SBarry Smith   snes->lagpreconditioner = lag;
34143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3415a8054027SBarry Smith }
3416a8054027SBarry Smith 
3417efd51863SBarry Smith /*@
3418f6dfbefdSBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do
3419efd51863SBarry Smith 
3420c3339decSBarry Smith    Logically Collective
3421efd51863SBarry Smith 
3422efd51863SBarry Smith    Input Parameters:
3423f6dfbefdSBarry Smith +  snes - the `SNES` context
3424efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
3425efd51863SBarry Smith 
3426f6dfbefdSBarry Smith    Options Database Key:
342767b8a455SSatish Balay .    -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess
3428efd51863SBarry Smith 
3429efd51863SBarry Smith    Level: intermediate
3430efd51863SBarry Smith 
3431f6dfbefdSBarry Smith    Note:
3432f6dfbefdSBarry Smith    Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing.
3433c0df2a02SJed Brown 
3434f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()`
3435efd51863SBarry Smith @*/
3436d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps)
3437d71ae5a4SJacob Faibussowitsch {
3438efd51863SBarry Smith   PetscFunctionBegin;
3439efd51863SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3440efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes, steps, 2);
3441efd51863SBarry Smith   snes->gridsequence = steps;
34423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3443efd51863SBarry Smith }
3444efd51863SBarry Smith 
3445fa19ca70SBarry Smith /*@
3446f6dfbefdSBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do
3447fa19ca70SBarry Smith 
3448c3339decSBarry Smith    Logically Collective
3449fa19ca70SBarry Smith 
3450fa19ca70SBarry Smith    Input Parameter:
3451f6dfbefdSBarry Smith .  snes - the `SNES` context
3452fa19ca70SBarry Smith 
3453fa19ca70SBarry Smith    Output Parameter:
3454fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
3455fa19ca70SBarry Smith 
3456f6dfbefdSBarry Smith    Options Database Key:
345767b8a455SSatish Balay .    -snes_grid_sequence <steps> - set number of refinements
3458fa19ca70SBarry Smith 
3459fa19ca70SBarry Smith    Level: intermediate
3460fa19ca70SBarry Smith 
3461f6dfbefdSBarry Smith    Note:
3462f6dfbefdSBarry Smith    Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing.
3463fa19ca70SBarry Smith 
3464db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()`
3465fa19ca70SBarry Smith @*/
3466d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps)
3467d71ae5a4SJacob Faibussowitsch {
3468fa19ca70SBarry Smith   PetscFunctionBegin;
3469fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3470fa19ca70SBarry Smith   *steps = snes->gridsequence;
34713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3472fa19ca70SBarry Smith }
3473fa19ca70SBarry Smith 
3474a8054027SBarry Smith /*@
3475f6dfbefdSBarry Smith    SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt
3476a8054027SBarry Smith 
34773f9fe445SBarry Smith    Not Collective
3478a8054027SBarry Smith 
3479a8054027SBarry Smith    Input Parameter:
3480f6dfbefdSBarry Smith .  snes - the `SNES` context
3481a8054027SBarry Smith 
3482a8054027SBarry Smith    Output Parameter:
3483a8054027SBarry 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
34843b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3485a8054027SBarry Smith 
3486a8054027SBarry Smith    Options Database Keys:
34873d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34883d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34893d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34903d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3491a8054027SBarry Smith 
3492a8054027SBarry Smith    Notes:
3493a8054027SBarry Smith    The default is 1
3494f6dfbefdSBarry Smith 
3495a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3496a8054027SBarry Smith 
3497a8054027SBarry Smith    Level: intermediate
3498a8054027SBarry Smith 
3499f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3500a8054027SBarry Smith @*/
3501d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag)
3502d71ae5a4SJacob Faibussowitsch {
3503a8054027SBarry Smith   PetscFunctionBegin;
35040700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3505a8054027SBarry Smith   *lag = snes->lagpreconditioner;
35063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3507a8054027SBarry Smith }
3508a8054027SBarry Smith 
3509e35cf81dSBarry Smith /*@
3510f6dfbefdSBarry Smith    SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how
3511e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3512e35cf81dSBarry Smith 
3513c3339decSBarry Smith    Logically Collective
3514e35cf81dSBarry Smith 
3515e35cf81dSBarry Smith    Input Parameters:
3516f6dfbefdSBarry Smith +  snes - the `SNES` context
3517e35cf81dSBarry 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
3518fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3519e35cf81dSBarry Smith 
3520e35cf81dSBarry Smith    Options Database Keys:
35213d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35223d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35233d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35243d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag.
3525e35cf81dSBarry Smith 
3526e35cf81dSBarry Smith    Notes:
3527e35cf81dSBarry Smith    The default is 1
3528f6dfbefdSBarry Smith 
3529e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3530f6dfbefdSBarry Smith 
3531fe3ffe1eSBarry Smith    If  -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed
3532fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3533e35cf81dSBarry Smith 
3534e35cf81dSBarry Smith    Level: intermediate
3535e35cf81dSBarry Smith 
3536f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3537e35cf81dSBarry Smith @*/
3538d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag)
3539d71ae5a4SJacob Faibussowitsch {
3540e35cf81dSBarry Smith   PetscFunctionBegin;
35410700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
35425f80ce2aSJacob Faibussowitsch   PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater");
35435f80ce2aSJacob Faibussowitsch   PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0");
3544c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, lag, 2);
3545e35cf81dSBarry Smith   snes->lagjacobian = lag;
35463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3547e35cf81dSBarry Smith }
3548e35cf81dSBarry Smith 
3549e35cf81dSBarry Smith /*@
3550f6dfbefdSBarry Smith    SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt
3551e35cf81dSBarry Smith 
35523f9fe445SBarry Smith    Not Collective
3553e35cf81dSBarry Smith 
3554e35cf81dSBarry Smith    Input Parameter:
3555f6dfbefdSBarry Smith .  snes - the `SNES` context
3556e35cf81dSBarry Smith 
3557e35cf81dSBarry Smith    Output Parameter:
3558e35cf81dSBarry 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
3559e35cf81dSBarry Smith          the Jacobian is built etc.
3560e35cf81dSBarry Smith 
3561e35cf81dSBarry Smith    Notes:
3562e35cf81dSBarry Smith    The default is 1
3563f6dfbefdSBarry Smith 
3564f6dfbefdSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called.
3565e35cf81dSBarry Smith 
3566e35cf81dSBarry Smith    Level: intermediate
3567e35cf81dSBarry Smith 
3568f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3569e35cf81dSBarry Smith 
3570e35cf81dSBarry Smith @*/
3571d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag)
3572d71ae5a4SJacob Faibussowitsch {
3573e35cf81dSBarry Smith   PetscFunctionBegin;
35740700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3575e35cf81dSBarry Smith   *lag = snes->lagjacobian;
35763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3577e35cf81dSBarry Smith }
3578e35cf81dSBarry Smith 
357937ec4e1aSPeter Brune /*@
3580f6dfbefdSBarry Smith    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves
358137ec4e1aSPeter Brune 
3582c3339decSBarry Smith    Logically collective
358337ec4e1aSPeter Brune 
3584d8d19677SJose E. Roman    Input Parameters:
3585f6dfbefdSBarry Smith +  snes - the `SNES` context
35869d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
358737ec4e1aSPeter Brune 
358837ec4e1aSPeter Brune    Options Database Keys:
35893d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35903d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35913d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35923d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
35933d5a8a6aSBarry Smith 
359495452b02SPatrick Sanan    Notes:
3595f6dfbefdSBarry Smith     Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that.
3596f6dfbefdSBarry Smith 
359795452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
359837ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
359937ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
360037ec4e1aSPeter Brune 
3601f6dfbefdSBarry Smith    Level: advanced
360237ec4e1aSPeter Brune 
3603f6dfbefdSBarry Smith .seealso: `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()`
360437ec4e1aSPeter Brune @*/
3605d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg)
3606d71ae5a4SJacob Faibussowitsch {
360737ec4e1aSPeter Brune   PetscFunctionBegin;
360837ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
360937ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes, flg, 2);
361037ec4e1aSPeter Brune   snes->lagjac_persist = flg;
36113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
361237ec4e1aSPeter Brune }
361337ec4e1aSPeter Brune 
361437ec4e1aSPeter Brune /*@
3615d8e291bfSBarry Smith    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
361637ec4e1aSPeter Brune 
3617c3339decSBarry Smith    Logically Collective
361837ec4e1aSPeter Brune 
3619d8d19677SJose E. Roman    Input Parameters:
3620f6dfbefdSBarry Smith +  snes - the `SNES` context
36219d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
362237ec4e1aSPeter Brune 
362337ec4e1aSPeter Brune    Options Database Keys:
36243d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
36253d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
36263d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
36273d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
362837ec4e1aSPeter Brune 
362995452b02SPatrick Sanan    Notes:
3630f6dfbefdSBarry Smith     Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that.
3631f6dfbefdSBarry Smith 
363295452b02SPatrick Sanan    This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
363337ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
363437ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
363537ec4e1aSPeter Brune 
363637ec4e1aSPeter Brune    Level: developer
363737ec4e1aSPeter Brune 
3638f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()`
363937ec4e1aSPeter Brune @*/
3640d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg)
3641d71ae5a4SJacob Faibussowitsch {
364237ec4e1aSPeter Brune   PetscFunctionBegin;
364337ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
364437ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes, flg, 2);
364537ec4e1aSPeter Brune   snes->lagpre_persist = flg;
36463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364737ec4e1aSPeter Brune }
364837ec4e1aSPeter Brune 
36499b94acceSBarry Smith /*@
3650f6dfbefdSBarry Smith    SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm
3651be5caee7SBarry Smith 
3652c3339decSBarry Smith    Logically Collective
3653be5caee7SBarry Smith 
3654be5caee7SBarry Smith    Input Parameters:
3655f6dfbefdSBarry Smith +  snes - the `SNES` context
3656f6dfbefdSBarry Smith -  force - `PETSC_TRUE` require at least one iteration
3657be5caee7SBarry Smith 
3658f6dfbefdSBarry Smith    Options Database Key:
3659be5caee7SBarry Smith .    -snes_force_iteration <force> - Sets forcing an iteration
3660be5caee7SBarry Smith 
3661f6dfbefdSBarry Smith    Note:
3662f6dfbefdSBarry Smith    This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution
3663be5caee7SBarry Smith 
3664be5caee7SBarry Smith    Level: intermediate
3665be5caee7SBarry Smith 
3666f6dfbefdSBarry Smith .seealso: `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3667be5caee7SBarry Smith @*/
3668d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force)
3669d71ae5a4SJacob Faibussowitsch {
3670be5caee7SBarry Smith   PetscFunctionBegin;
3671be5caee7SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3672be5caee7SBarry Smith   snes->forceiteration = force;
36733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3674be5caee7SBarry Smith }
3675be5caee7SBarry Smith 
367685216dc7SFande Kong /*@
3677f6dfbefdSBarry Smith    SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm
367885216dc7SFande Kong 
3679c3339decSBarry Smith    Logically Collective
368085216dc7SFande Kong 
368185216dc7SFande Kong    Input Parameters:
3682f6dfbefdSBarry Smith .  snes - the `SNES` context
368385216dc7SFande Kong 
368485216dc7SFande Kong    Output Parameter:
368585216dc7SFande Kong .  force - PETSC_TRUE requires at least one iteration.
368685216dc7SFande Kong 
368706dd6b0eSSatish Balay    Level: intermediate
368806dd6b0eSSatish Balay 
3689f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
369085216dc7SFande Kong @*/
3691d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force)
3692d71ae5a4SJacob Faibussowitsch {
369385216dc7SFande Kong   PetscFunctionBegin;
369485216dc7SFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
369585216dc7SFande Kong   *force = snes->forceiteration;
36963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
369785216dc7SFande Kong }
3698be5caee7SBarry Smith 
3699be5caee7SBarry Smith /*@
3700f6dfbefdSBarry Smith    SNESSetTolerances - Sets `SNES` various parameters used in convergence tests.
37019b94acceSBarry Smith 
3702c3339decSBarry Smith    Logically Collective
3703c7afd0dbSLois Curfman McInnes 
37049b94acceSBarry Smith    Input Parameters:
3705f6dfbefdSBarry Smith +  snes - the `SNES` context
370670441072SBarry Smith .  abstol - absolute convergence tolerance
370733174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
37085358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
3709f6dfbefdSBarry Smith .  maxit - maximum number of iterations, default 50.
3710f6dfbefdSBarry Smith -  maxf - maximum number of function evaluations (-1 indicates no limit), default 1000
3711fee21e36SBarry Smith 
371233174efeSLois Curfman McInnes    Options Database Keys:
371370441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3714c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3715c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3716c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3717c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
37189b94acceSBarry Smith 
371936851e7fSLois Curfman McInnes    Level: intermediate
372036851e7fSLois Curfman McInnes 
3721f6dfbefdSBarry Smith .seealso: `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()`
37229b94acceSBarry Smith @*/
3723d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf)
3724d71ae5a4SJacob Faibussowitsch {
37253a40ed3dSBarry Smith   PetscFunctionBegin;
37260700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3727c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, abstol, 2);
3728c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, rtol, 3);
3729c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, stol, 4);
3730c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, maxit, 5);
3731c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, maxf, 6);
3732c5eb9154SBarry Smith 
3733ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
37345f80ce2aSJacob Faibussowitsch     PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol);
3735ab54825eSJed Brown     snes->abstol = abstol;
3736ab54825eSJed Brown   }
3737ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
37385f80ce2aSJacob 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);
3739ab54825eSJed Brown     snes->rtol = rtol;
3740ab54825eSJed Brown   }
3741ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
37425f80ce2aSJacob Faibussowitsch     PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol);
3743c60f73f4SPeter Brune     snes->stol = stol;
3744ab54825eSJed Brown   }
3745ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
374663a3b9bcSJacob Faibussowitsch     PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit);
3747ab54825eSJed Brown     snes->max_its = maxit;
3748ab54825eSJed Brown   }
3749ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
375063a3b9bcSJacob Faibussowitsch     PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf);
3751ab54825eSJed Brown     snes->max_funcs = maxf;
3752ab54825eSJed Brown   }
375388976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
37543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37559b94acceSBarry Smith }
37569b94acceSBarry Smith 
3757e4d06f11SPatrick Farrell /*@
3758f6dfbefdSBarry Smith    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test.
3759e4d06f11SPatrick Farrell 
3760c3339decSBarry Smith    Logically Collective
3761e4d06f11SPatrick Farrell 
3762e4d06f11SPatrick Farrell    Input Parameters:
3763f6dfbefdSBarry Smith +  snes - the `SNES` context
3764f6dfbefdSBarry Smith -  divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4
3765e4d06f11SPatrick Farrell 
3766f6dfbefdSBarry Smith    Options Database Key:
3767a2b725a8SWilliam Gropp .    -snes_divergence_tolerance <divtol> - Sets divtol
3768e4d06f11SPatrick Farrell 
3769e4d06f11SPatrick Farrell    Level: intermediate
3770e4d06f11SPatrick Farrell 
3771f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance`
3772e4d06f11SPatrick Farrell @*/
3773d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol)
3774d71ae5a4SJacob Faibussowitsch {
3775e4d06f11SPatrick Farrell   PetscFunctionBegin;
3776e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3777e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes, divtol, 2);
3778e4d06f11SPatrick Farrell 
3779e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3780e4d06f11SPatrick Farrell     snes->divtol = divtol;
37819371c9d4SSatish Balay   } else {
3782e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3783e4d06f11SPatrick Farrell   }
37843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3785e4d06f11SPatrick Farrell }
3786e4d06f11SPatrick Farrell 
37879b94acceSBarry Smith /*@
378833174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
378933174efeSLois Curfman McInnes 
3790c7afd0dbSLois Curfman McInnes    Not Collective
3791c7afd0dbSLois Curfman McInnes 
379233174efeSLois Curfman McInnes    Input Parameters:
3793f6dfbefdSBarry Smith +  snes - the `SNES` context
379485385478SLisandro Dalcin .  atol - absolute convergence tolerance
379533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
379633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
379733174efeSLois Curfman McInnes            of the change in the solution between steps
379833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3799c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3800fee21e36SBarry Smith 
3801f6dfbefdSBarry Smith    Note:
38020298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
380333174efeSLois Curfman McInnes 
380436851e7fSLois Curfman McInnes    Level: intermediate
380536851e7fSLois Curfman McInnes 
3806f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTolerances()`
380733174efeSLois Curfman McInnes @*/
3808d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf)
3809d71ae5a4SJacob Faibussowitsch {
38103a40ed3dSBarry Smith   PetscFunctionBegin;
38110700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
381285385478SLisandro Dalcin   if (atol) *atol = snes->abstol;
381333174efeSLois Curfman McInnes   if (rtol) *rtol = snes->rtol;
3814c60f73f4SPeter Brune   if (stol) *stol = snes->stol;
381533174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
381633174efeSLois Curfman McInnes   if (maxf) *maxf = snes->max_funcs;
38173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
381833174efeSLois Curfman McInnes }
381933174efeSLois Curfman McInnes 
3820e4d06f11SPatrick Farrell /*@
3821e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3822e4d06f11SPatrick Farrell 
3823e4d06f11SPatrick Farrell    Not Collective
3824e4d06f11SPatrick Farrell 
3825e4d06f11SPatrick Farrell    Input Parameters:
3826f6dfbefdSBarry Smith +  snes - the `SNES` context
3827e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3828e4d06f11SPatrick Farrell 
3829e4d06f11SPatrick Farrell    Level: intermediate
3830e4d06f11SPatrick Farrell 
3831f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetDivergenceTolerance()`
3832e4d06f11SPatrick Farrell @*/
3833d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol)
3834d71ae5a4SJacob Faibussowitsch {
3835e4d06f11SPatrick Farrell   PetscFunctionBegin;
3836e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3837e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
38383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3839e4d06f11SPatrick Farrell }
3840e4d06f11SPatrick Farrell 
384133174efeSLois Curfman McInnes /*@
38429b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
38439b94acceSBarry Smith 
3844c3339decSBarry Smith    Logically Collective
3845fee21e36SBarry Smith 
3846c7afd0dbSLois Curfman McInnes    Input Parameters:
3847f6dfbefdSBarry Smith +  snes - the `SNES` context
3848c7afd0dbSLois Curfman McInnes -  tol - tolerance
3849c7afd0dbSLois Curfman McInnes 
38509b94acceSBarry Smith    Options Database Key:
3851c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
38529b94acceSBarry Smith 
385336851e7fSLois Curfman McInnes    Level: intermediate
385436851e7fSLois Curfman McInnes 
3855f6dfbefdSBarry Smith .seealso: `SNES`, `SNESNEWTONTRDC`, `SNESSetTolerances()`
38569b94acceSBarry Smith @*/
3857d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol)
3858d71ae5a4SJacob Faibussowitsch {
38593a40ed3dSBarry Smith   PetscFunctionBegin;
38600700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
3861c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, tol, 2);
38629b94acceSBarry Smith   snes->deltatol = tol;
38633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38649b94acceSBarry Smith }
38659b94acceSBarry Smith 
38666ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *);
38676ba87a44SLisandro Dalcin 
3868d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx)
3869d71ae5a4SJacob Faibussowitsch {
3870b271bb04SBarry Smith   PetscDrawLG      lg;
3871b271bb04SBarry Smith   PetscReal        x, y, per;
3872b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3873b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3874b271bb04SBarry Smith   PetscDraw        draw;
3875b271bb04SBarry Smith 
3876459f5d12SBarry Smith   PetscFunctionBegin;
38774d4332d5SBarry Smith   PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4);
38789566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg));
38799566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
38809566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg, &draw));
38819566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw, "Residual norm"));
3882b271bb04SBarry Smith   x = (PetscReal)n;
388377b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
388494c9c6d3SKarl Rupp   else y = -15.0;
38859566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
38866934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
38879566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
38889566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3889b271bb04SBarry Smith   }
3890b271bb04SBarry Smith 
38919566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg));
38929566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
38939566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg, &draw));
38949566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt"));
38959566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes, n, &per));
3896b271bb04SBarry Smith   x = (PetscReal)n;
3897b271bb04SBarry Smith   y = 100.0 * per;
38989566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
38996934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
39009566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
39019566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3902b271bb04SBarry Smith   }
3903b271bb04SBarry Smith 
39049566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg));
39059371c9d4SSatish Balay   if (!n) {
39069371c9d4SSatish Balay     prev = rnorm;
39079371c9d4SSatish Balay     PetscCall(PetscDrawLGReset(lg));
39089371c9d4SSatish Balay   }
39099566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg, &draw));
39109566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm"));
3911b271bb04SBarry Smith   x = (PetscReal)n;
3912b271bb04SBarry Smith   y = (prev - rnorm) / prev;
39139566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
39146934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
39159566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
39169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3917b271bb04SBarry Smith   }
3918b271bb04SBarry Smith 
39199566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg));
39209566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
39219566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg, &draw));
39229566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)"));
3923b271bb04SBarry Smith   x = (PetscReal)n;
3924b271bb04SBarry Smith   y = (prev - rnorm) / (prev * per);
3925b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
39269566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddPoint(lg, &x, &y));
3927b271bb04SBarry Smith   }
39286934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
39299566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
39309566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3931b271bb04SBarry Smith   }
3932b271bb04SBarry Smith   prev = rnorm;
39333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3934b271bb04SBarry Smith }
3935b271bb04SBarry Smith 
3936228d79bcSJed Brown /*@
3937228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3938228d79bcSJed Brown 
3939c3339decSBarry Smith    Collective
3940228d79bcSJed Brown 
3941228d79bcSJed Brown    Input Parameters:
3942f6dfbefdSBarry Smith +  snes - nonlinear solver context obtained from `SNESCreate()`
3943228d79bcSJed Brown .  iter - iteration number
3944228d79bcSJed Brown -  rnorm - relative norm of the residual
3945228d79bcSJed Brown 
3946f6dfbefdSBarry Smith    Note:
3947f6dfbefdSBarry Smith    This routine is called by the `SNES` implementations.
3948228d79bcSJed Brown    It does not typically need to be called by the user.
3949228d79bcSJed Brown 
3950228d79bcSJed Brown    Level: developer
3951228d79bcSJed Brown 
3952f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorSet()`
3953228d79bcSJed Brown @*/
3954d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm)
3955d71ae5a4SJacob Faibussowitsch {
39567a03ce2fSLisandro Dalcin   PetscInt i, n = snes->numbermonitors;
39577a03ce2fSLisandro Dalcin 
39587a03ce2fSLisandro Dalcin   PetscFunctionBegin;
39599566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(snes->vec_sol));
396048a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i]));
39619566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(snes->vec_sol));
39623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39637a03ce2fSLisandro Dalcin }
39647a03ce2fSLisandro Dalcin 
39659b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
39669b94acceSBarry Smith 
3967bf388a1fSBarry Smith /*MC
3968f6dfbefdSBarry Smith     SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver
3969bf388a1fSBarry Smith 
3970bf388a1fSBarry Smith      Synopsis:
3971aaa7dc30SBarry Smith      #include <petscsnes.h>
3972bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3973bf388a1fSBarry Smith 
3974c3339decSBarry Smith      Collective
39751843f636SBarry Smith 
39761843f636SBarry Smith     Input Parameters:
3977f6dfbefdSBarry Smith +    snes - the `SNES` context
3978bf388a1fSBarry Smith .    its - iteration number
3979bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3980bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3981bf388a1fSBarry Smith 
3982878cb397SSatish Balay    Level: advanced
3983878cb397SSatish Balay 
3984f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()`
3985bf388a1fSBarry Smith M*/
3986bf388a1fSBarry Smith 
39879b94acceSBarry Smith /*@C
3988a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
39899b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
39909b94acceSBarry Smith    progress.
39919b94acceSBarry Smith 
3992c3339decSBarry Smith    Logically Collective
3993fee21e36SBarry Smith 
3994c7afd0dbSLois Curfman McInnes    Input Parameters:
3995f6dfbefdSBarry Smith +  snes - the `SNES` context
3996f6dfbefdSBarry Smith .  f - the monitor function, see `SNESMonitorFunction` for the calling sequence
3997b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
39980298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3999b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
40000298fd71SBarry Smith           (may be NULL)
40019b94acceSBarry Smith 
40029665c990SLois Curfman McInnes    Options Database Keys:
4003f6dfbefdSBarry Smith +    -snes_monitor        - sets `SNESMonitorDefault()`
4004798534f6SMatthew G. Knepley .    -snes_monitor draw::draw_lg - sets line graph monitor,
4005cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
4006c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
4007a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
4008c7afd0dbSLois Curfman McInnes                             does not cancel those set via
4009c7afd0dbSLois Curfman McInnes                             the options database.
40109665c990SLois Curfman McInnes 
4011f6dfbefdSBarry Smith    Note:
40126bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
4013f6dfbefdSBarry Smith    `SNESMonitorSet()` multiple times; all will be called in the
40146bc08f3fSLois Curfman McInnes    order in which they were set.
4015639f9d9dSBarry Smith 
4016f6dfbefdSBarry Smith    Fortran Note:
4017f6dfbefdSBarry Smith    Only a single monitor function can be set for each `SNES` object
4018025f1a04SBarry Smith 
401936851e7fSLois Curfman McInnes    Level: intermediate
402036851e7fSLois Curfman McInnes 
4021f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
40229b94acceSBarry Smith @*/
4023d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **))
4024d71ae5a4SJacob Faibussowitsch {
4025b90d0a6eSBarry Smith   PetscInt  i;
402678064530SBarry Smith   PetscBool identical;
4027b90d0a6eSBarry Smith 
40283a40ed3dSBarry Smith   PetscFunctionBegin;
40290700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4030b90d0a6eSBarry Smith   for (i = 0; i < snes->numbermonitors; i++) {
40319566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical));
40323ba16761SJacob Faibussowitsch     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4033649052a6SBarry Smith   }
40345f80ce2aSJacob Faibussowitsch   PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set");
40356e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
4036b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4037639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void *)mctx;
40383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40399b94acceSBarry Smith }
40409b94acceSBarry Smith 
4041a278d85bSSatish Balay /*@
4042f6dfbefdSBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a `SNES` object.
40435cd90555SBarry Smith 
4044c3339decSBarry Smith    Logically Collective
4045c7afd0dbSLois Curfman McInnes 
40465cd90555SBarry Smith    Input Parameters:
4047f6dfbefdSBarry Smith .  snes - the `SNES` context
40485cd90555SBarry Smith 
40491a480d89SAdministrator    Options Database Key:
4050a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
4051a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
4052c7afd0dbSLois Curfman McInnes     set via the options database
40535cd90555SBarry Smith 
4054f6dfbefdSBarry Smith    Note:
4055f6dfbefdSBarry Smith    There is no way to clear one specific monitor from a `SNES` object.
40565cd90555SBarry Smith 
405736851e7fSLois Curfman McInnes    Level: intermediate
405836851e7fSLois Curfman McInnes 
4059f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()`
40605cd90555SBarry Smith @*/
4061d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes)
4062d71ae5a4SJacob Faibussowitsch {
4063d952e501SBarry Smith   PetscInt i;
4064d952e501SBarry Smith 
40655cd90555SBarry Smith   PetscFunctionBegin;
40660700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4067d952e501SBarry Smith   for (i = 0; i < snes->numbermonitors; i++) {
406848a46eb9SPierre Jolivet     if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4069d952e501SBarry Smith   }
40705cd90555SBarry Smith   snes->numbermonitors = 0;
40713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40725cd90555SBarry Smith }
40735cd90555SBarry Smith 
4074bf388a1fSBarry Smith /*MC
4075bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4076bf388a1fSBarry Smith 
4077bf388a1fSBarry Smith      Synopsis:
4078aaa7dc30SBarry Smith      #include <petscsnes.h>
4079bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
4080bf388a1fSBarry Smith 
4081c3339decSBarry Smith      Collective
40821843f636SBarry Smith 
40831843f636SBarry Smith     Input Parameters:
4084f6dfbefdSBarry Smith +    snes - the `SNES` context
4085bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
4086bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
4087bf388a1fSBarry Smith .    gnorm - 2-norm of current step
40881843f636SBarry Smith .    f - 2-norm of function
40891843f636SBarry Smith -    cctx - [optional] convergence context
40901843f636SBarry Smith 
40911843f636SBarry Smith     Output Parameter:
40921843f636SBarry Smith .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4093bf388a1fSBarry Smith 
4094878cb397SSatish Balay    Level: intermediate
4095bf388a1fSBarry Smith 
4096f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4097bf388a1fSBarry Smith M*/
4098bf388a1fSBarry Smith 
40999b94acceSBarry Smith /*@C
41009b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
41019b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
41029b94acceSBarry Smith 
4103c3339decSBarry Smith    Logically Collective
4104fee21e36SBarry Smith 
4105c7afd0dbSLois Curfman McInnes    Input Parameters:
4106f6dfbefdSBarry Smith +  snes - the `SNES` context
4107f6dfbefdSBarry Smith .  `SNESConvergenceTestFunction` - routine to test for convergence
41080298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
4109cf90aa19SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran)
41109b94acceSBarry Smith 
411136851e7fSLois Curfman McInnes    Level: advanced
411236851e7fSLois Curfman McInnes 
4113f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
41149b94acceSBarry Smith @*/
4115d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *))
4116d71ae5a4SJacob Faibussowitsch {
41173a40ed3dSBarry Smith   PetscFunctionBegin;
41180700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4119e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
41201baa6e33SBarry Smith   if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
4121bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
41227f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
412385385478SLisandro Dalcin   snes->cnvP                  = cctx;
41243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
41259b94acceSBarry Smith }
41269b94acceSBarry Smith 
412752baeb72SSatish Balay /*@
4128f6dfbefdSBarry Smith    SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped.
4129184914b5SBarry Smith 
4130184914b5SBarry Smith    Not Collective
4131184914b5SBarry Smith 
4132184914b5SBarry Smith    Input Parameter:
4133f6dfbefdSBarry Smith .  snes - the `SNES` context
4134184914b5SBarry Smith 
4135184914b5SBarry Smith    Output Parameter:
4136f6dfbefdSBarry Smith .  reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists
4137184914b5SBarry Smith 
4138f6dfbefdSBarry Smith    Options Database Key:
41396a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
41406a4d7782SBarry Smith 
4141184914b5SBarry Smith    Level: intermediate
4142184914b5SBarry Smith 
4143f6dfbefdSBarry Smith    Note:
4144f6dfbefdSBarry Smith     Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`.
4145184914b5SBarry Smith 
4146f6dfbefdSBarry Smith .seealso: `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()`
4147184914b5SBarry Smith @*/
4148d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason)
4149d71ae5a4SJacob Faibussowitsch {
4150184914b5SBarry Smith   PetscFunctionBegin;
41510700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
41524482741eSBarry Smith   PetscValidPointer(reason, 2);
4153184914b5SBarry Smith   *reason = snes->reason;
41543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4155184914b5SBarry Smith }
4156184914b5SBarry Smith 
4157c4421ceaSFande Kong /*@C
4158f6dfbefdSBarry Smith    SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason`
4159c4421ceaSFande Kong 
4160c4421ceaSFande Kong    Not Collective
4161c4421ceaSFande Kong 
4162c4421ceaSFande Kong    Input Parameter:
4163f6dfbefdSBarry Smith .  snes - the `SNES` context
4164c4421ceaSFande Kong 
4165c4421ceaSFande Kong    Output Parameter:
4166c4421ceaSFande Kong .  strreason - a human readable string that describes SNES converged reason
4167c4421ceaSFande Kong 
416899c90e12SSatish Balay    Level: beginner
4169c4421ceaSFande Kong 
4170f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetConvergedReason()`
4171c4421ceaSFande Kong @*/
4172d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason)
4173d71ae5a4SJacob Faibussowitsch {
4174c4421ceaSFande Kong   PetscFunctionBegin;
4175c4421ceaSFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4176dadcf809SJacob Faibussowitsch   PetscValidPointer(strreason, 2);
4177c4421ceaSFande Kong   *strreason = SNESConvergedReasons[snes->reason];
41783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4179c4421ceaSFande Kong }
4180c4421ceaSFande Kong 
418133866048SMatthew G. Knepley /*@
4182f6dfbefdSBarry Smith    SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped.
418333866048SMatthew G. Knepley 
418433866048SMatthew G. Knepley    Not Collective
418533866048SMatthew G. Knepley 
418633866048SMatthew G. Knepley    Input Parameters:
4187f6dfbefdSBarry Smith +  snes - the `SNES` context
4188f6dfbefdSBarry Smith -  reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the
418933866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
419033866048SMatthew G. Knepley 
4191f6dfbefdSBarry Smith    Level: developer
4192f6dfbefdSBarry Smith 
4193f6dfbefdSBarry Smith    Developer Note:
4194f6dfbefdSBarry Smith    Called inside the various `SNESSolve()` implementations
419533866048SMatthew G. Knepley 
4196db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
419733866048SMatthew G. Knepley @*/
4198d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason)
4199d71ae5a4SJacob Faibussowitsch {
420033866048SMatthew G. Knepley   PetscFunctionBegin;
420133866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
420233866048SMatthew G. Knepley   snes->reason = reason;
42033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
420433866048SMatthew G. Knepley }
420533866048SMatthew G. Knepley 
4206c9005455SLois Curfman McInnes /*@
4207c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
4208c9005455SLois Curfman McInnes 
4209c3339decSBarry Smith    Logically Collective
4210fee21e36SBarry Smith 
4211c7afd0dbSLois Curfman McInnes    Input Parameters:
4212f6dfbefdSBarry Smith +  snes - iterative context obtained from `SNESCreate()`
42138c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
4214cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
4215758f92a0SBarry Smith .  na  - size of a and its
4216f6dfbefdSBarry Smith -  reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero,
4217758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
4218c7afd0dbSLois Curfman McInnes 
4219308dcc3eSBarry Smith    Notes:
4220f6dfbefdSBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a
4221308dcc3eSBarry Smith    default array of length 10000 is allocated.
4222308dcc3eSBarry Smith 
4223c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
4224c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
4225c9005455SLois Curfman McInnes    during the section of code that is being timed.
4226c9005455SLois Curfman McInnes 
422736851e7fSLois Curfman McInnes    Level: intermediate
422836851e7fSLois Curfman McInnes 
4229f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()`
4230c9005455SLois Curfman McInnes @*/
4231d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset)
4232d71ae5a4SJacob Faibussowitsch {
42333a40ed3dSBarry Smith   PetscFunctionBegin;
42340700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4235064a246eSJacob Faibussowitsch   if (a) PetscValidRealPointer(a, 2);
4236a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its, 3);
42377a1ec6d4SBarry Smith   if (!a) {
4238308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
42399566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(na, &a, na, &its));
4240071fcb05SBarry Smith     snes->conv_hist_alloc = PETSC_TRUE;
4241308dcc3eSBarry Smith   }
4242c9005455SLois Curfman McInnes   snes->conv_hist       = a;
4243758f92a0SBarry Smith   snes->conv_hist_its   = its;
4244115dd874SBarry Smith   snes->conv_hist_max   = (size_t)na;
4245a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
4246758f92a0SBarry Smith   snes->conv_hist_reset = reset;
42473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4248758f92a0SBarry Smith }
4249758f92a0SBarry Smith 
4250d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB)
4251c6db04a5SJed Brown   #include <engine.h> /* MATLAB include file */
4252c6db04a5SJed Brown   #include <mex.h>    /* MATLAB include file */
425399e0435eSBarry Smith 
4254d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4255d71ae5a4SJacob Faibussowitsch {
4256308dcc3eSBarry Smith   mxArray   *mat;
4257308dcc3eSBarry Smith   PetscInt   i;
4258308dcc3eSBarry Smith   PetscReal *ar;
4259308dcc3eSBarry Smith 
4260308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL);
4261308dcc3eSBarry Smith   ar  = (PetscReal *)mxGetData(mat);
4262f5af7f23SKarl Rupp   for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
426311cc89d2SBarry Smith   return mat;
4264308dcc3eSBarry Smith }
4265308dcc3eSBarry Smith #endif
4266308dcc3eSBarry Smith 
42670c4c9dddSBarry Smith /*@C
4268758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4269758f92a0SBarry Smith 
42703f9fe445SBarry Smith    Not Collective
4271758f92a0SBarry Smith 
4272758f92a0SBarry Smith    Input Parameter:
4273f6dfbefdSBarry Smith .  snes - iterative context obtained from `SNESCreate()`
4274758f92a0SBarry Smith 
4275758f92a0SBarry Smith    Output Parameters:
4276f6dfbefdSBarry Smith +  a   - array to hold history, usually was set with `SNESSetConvergenceHistory()`
4277758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
4278758f92a0SBarry Smith          negative if not converged) for each solve.
4279758f92a0SBarry Smith -  na  - size of a and its
4280758f92a0SBarry Smith 
4281758f92a0SBarry Smith    Notes:
4282758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
4283758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4284758f92a0SBarry Smith 
4285758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
4286758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
4287758f92a0SBarry Smith    during the section of code that is being timed.
4288758f92a0SBarry Smith 
4289758f92a0SBarry Smith    Level: intermediate
4290758f92a0SBarry Smith 
4291f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()`
4292758f92a0SBarry Smith @*/
4293d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na)
4294d71ae5a4SJacob Faibussowitsch {
4295758f92a0SBarry Smith   PetscFunctionBegin;
42960700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4297758f92a0SBarry Smith   if (a) *a = snes->conv_hist;
4298758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
4299115dd874SBarry Smith   if (na) *na = (PetscInt)snes->conv_hist_len;
43003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4301c9005455SLois Curfman McInnes }
4302c9005455SLois Curfman McInnes 
4303ac226902SBarry Smith /*@C
430476b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
4305eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
43067e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
430776b2cf59SMatthew Knepley 
4308c3339decSBarry Smith   Logically Collective
430976b2cf59SMatthew Knepley 
431076b2cf59SMatthew Knepley   Input Parameters:
4311a2b725a8SWilliam Gropp + snes - The nonlinear solver context
4312a2b725a8SWilliam Gropp - func - The function
431376b2cf59SMatthew Knepley 
431476b2cf59SMatthew Knepley   Calling sequence of func:
4315a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step);
431676b2cf59SMatthew Knepley 
431776b2cf59SMatthew Knepley . step - The current step of the iteration
431876b2cf59SMatthew Knepley 
4319fe97e370SBarry Smith   Level: advanced
4320fe97e370SBarry Smith 
43216b7fb656SBarry Smith   Note:
4322f6dfbefdSBarry 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
4323f6dfbefdSBarry Smith      to `SNESSetFunction()`, or `SNESSetPicard()`
4324fe97e370SBarry Smith      This is not used by most users.
432576b2cf59SMatthew Knepley 
43266b7fb656SBarry 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.
43276b7fb656SBarry Smith 
4328f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4329db781477SPatrick Sanan          `SNESMonitorSet()`, `SNESSetDivergenceTest()`
433076b2cf59SMatthew Knepley @*/
4331d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
4332d71ae5a4SJacob Faibussowitsch {
433376b2cf59SMatthew Knepley   PetscFunctionBegin;
43340700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4335e7788613SBarry Smith   snes->ops->update = func;
43363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
433776b2cf59SMatthew Knepley }
433876b2cf59SMatthew Knepley 
43399b94acceSBarry Smith /*
43409b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
43419b94acceSBarry Smith    positive parameter delta.
43429b94acceSBarry Smith 
43439b94acceSBarry Smith     Input Parameters:
4344f6dfbefdSBarry Smith +   snes - the `SNES` context
43459b94acceSBarry Smith .   y - approximate solution of linear system
43469b94acceSBarry Smith .   fnorm - 2-norm of current function
4347c7afd0dbSLois Curfman McInnes -   delta - trust region size
43489b94acceSBarry Smith 
43499b94acceSBarry Smith     Output Parameters:
4350c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
43519b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
43529b94acceSBarry Smith     region, and exceeds zero otherwise.
4353c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
43549b94acceSBarry Smith 
4355f6dfbefdSBarry Smith     Level: developer
43569b94acceSBarry Smith 
4357f6dfbefdSBarry Smith     Note:
4358f6dfbefdSBarry Smith     For non-trust region methods such as `SNESNEWTONLS`, the parameter delta
4359f6dfbefdSBarry Smith     is set to be the maximum allowable step size.
43609b94acceSBarry Smith */
4361d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm)
4362d71ae5a4SJacob Faibussowitsch {
4363064f8208SBarry Smith   PetscReal   nrm;
4364ea709b57SSatish Balay   PetscScalar cnorm;
43653a40ed3dSBarry Smith 
43663a40ed3dSBarry Smith   PetscFunctionBegin;
43670700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
43680700a824SBarry Smith   PetscValidHeaderSpecific(y, VEC_CLASSID, 2);
4369c9780b6fSBarry Smith   PetscCheckSameComm(snes, 1, y, 2);
4370184914b5SBarry Smith 
43719566063dSJacob Faibussowitsch   PetscCall(VecNorm(y, NORM_2, &nrm));
4372064f8208SBarry Smith   if (nrm > *delta) {
4373064f8208SBarry Smith     nrm     = *delta / nrm;
4374064f8208SBarry Smith     *gpnorm = (1.0 - nrm) * (*fnorm);
4375064f8208SBarry Smith     cnorm   = nrm;
43769566063dSJacob Faibussowitsch     PetscCall(VecScale(y, cnorm));
43779b94acceSBarry Smith     *ynorm = *delta;
43789b94acceSBarry Smith   } else {
43799b94acceSBarry Smith     *gpnorm = 0.0;
4380064f8208SBarry Smith     *ynorm  = nrm;
43819b94acceSBarry Smith   }
43823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
43839b94acceSBarry Smith }
43849b94acceSBarry Smith 
438591f3e32bSBarry Smith /*@C
4386f6dfbefdSBarry Smith    SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer
43872a359c20SBarry Smith 
4388c3339decSBarry Smith    Collective
43892a359c20SBarry Smith 
43902a359c20SBarry Smith    Parameter:
4391f6dfbefdSBarry Smith +  snes - iterative context obtained from `SNESCreate()`
43922a359c20SBarry Smith -  viewer - the viewer to display the reason
43932a359c20SBarry Smith 
43942a359c20SBarry Smith    Options Database Keys:
4395ee300463SSatish Balay +  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
4396ee300463SSatish Balay -  -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4397eafd5ff0SAlex Lindsay 
4398f6dfbefdSBarry Smith   Note:
4399f6dfbefdSBarry Smith      To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default,
4400f6dfbefdSBarry Smith      use `PETSC_VIEWER_FAILED` to only display a reason if it fails.
44012a359c20SBarry Smith 
44022a359c20SBarry Smith    Level: beginner
44032a359c20SBarry Smith 
4404f6dfbefdSBarry Smith .seealso: `SNESConvergedReason`, `PetscViewer`, `SNES`,
4405f6dfbefdSBarry Smith           `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`,
4406f6dfbefdSBarry Smith           `SNESConvergedReasonViewFromOptions()`,
4407db781477SPatrick Sanan           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
44082a359c20SBarry Smith @*/
4409d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer)
4410d71ae5a4SJacob Faibussowitsch {
441175cca76cSMatthew G. Knepley   PetscViewerFormat format;
44122a359c20SBarry Smith   PetscBool         isAscii;
44132a359c20SBarry Smith 
44142a359c20SBarry Smith   PetscFunctionBegin;
441519a666eeSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
44169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii));
44172a359c20SBarry Smith   if (isAscii) {
44189566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(viewer, &format));
44199566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel));
442075cca76cSMatthew G. Knepley     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
442175cca76cSMatthew G. Knepley       DM       dm;
442275cca76cSMatthew G. Knepley       Vec      u;
442375cca76cSMatthew G. Knepley       PetscDS  prob;
442475cca76cSMatthew G. Knepley       PetscInt Nf, f;
442595cbbfd3SMatthew G. Knepley       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
442695cbbfd3SMatthew G. Knepley       void    **exactCtx;
442775cca76cSMatthew G. Knepley       PetscReal error;
442875cca76cSMatthew G. Knepley 
44299566063dSJacob Faibussowitsch       PetscCall(SNESGetDM(snes, &dm));
44309566063dSJacob Faibussowitsch       PetscCall(SNESGetSolution(snes, &u));
44319566063dSJacob Faibussowitsch       PetscCall(DMGetDS(dm, &prob));
44329566063dSJacob Faibussowitsch       PetscCall(PetscDSGetNumFields(prob, &Nf));
44339566063dSJacob Faibussowitsch       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
44349566063dSJacob Faibussowitsch       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
44359566063dSJacob Faibussowitsch       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
44369566063dSJacob Faibussowitsch       PetscCall(PetscFree2(exactSol, exactCtx));
44379566063dSJacob Faibussowitsch       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
443863a3b9bcSJacob Faibussowitsch       else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
443975cca76cSMatthew G. Knepley     }
4440eafd5ff0SAlex Lindsay     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
44412a359c20SBarry Smith       if (((PetscObject)snes)->prefix) {
444263a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter));
44432a359c20SBarry Smith       } else {
444463a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
44452a359c20SBarry Smith       }
4446eafd5ff0SAlex Lindsay     } else if (snes->reason <= 0) {
44472a359c20SBarry Smith       if (((PetscObject)snes)->prefix) {
444863a3b9bcSJacob 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));
44492a359c20SBarry Smith       } else {
445063a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter));
44512a359c20SBarry Smith       }
44522a359c20SBarry Smith     }
44539566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel));
44542a359c20SBarry Smith   }
44553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
44562a359c20SBarry Smith }
44572a359c20SBarry Smith 
4458c4421ceaSFande Kong /*@C
4459c4421ceaSFande Kong    SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4460c4421ceaSFande Kong     end of the nonlinear solver to display the conver reason of the nonlinear solver.
4461c4421ceaSFande Kong 
4462c3339decSBarry Smith    Logically Collective
4463c4421ceaSFande Kong 
4464c4421ceaSFande Kong    Input Parameters:
4465f6dfbefdSBarry Smith +  snes - the `SNES` context
4466c4421ceaSFande Kong .  f - the snes converged reason view function
4467c4421ceaSFande Kong .  vctx - [optional] user-defined context for private data for the
4468c4421ceaSFande Kong           snes converged reason view routine (use NULL if no context is desired)
4469c4421ceaSFande Kong -  reasonviewdestroy - [optional] routine that frees reasonview context
4470c4421ceaSFande Kong           (may be NULL)
4471c4421ceaSFande Kong 
4472c4421ceaSFande Kong    Options Database Keys:
4473f6dfbefdSBarry Smith +    -snes_converged_reason        - sets a default `SNESConvergedReasonView()`
4474c4421ceaSFande Kong -    -snes_converged_reason_view_cancel - cancels all converged reason viewers that have
4475c4421ceaSFande Kong                             been hardwired into a code by
4476f6dfbefdSBarry Smith                             calls to `SNESConvergedReasonViewSet()`, but
4477c4421ceaSFande Kong                             does not cancel those set via
4478c4421ceaSFande Kong                             the options database.
4479c4421ceaSFande Kong 
4480f6dfbefdSBarry Smith    Note:
4481c4421ceaSFande Kong    Several different converged reason view routines may be set by calling
4482f6dfbefdSBarry Smith    `SNESConvergedReasonViewSet()` multiple times; all will be called in the
4483c4421ceaSFande Kong    order in which they were set.
4484c4421ceaSFande Kong 
4485c4421ceaSFande Kong    Level: intermediate
4486c4421ceaSFande Kong 
4487f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4488c4421ceaSFande Kong @*/
4489d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **))
4490d71ae5a4SJacob Faibussowitsch {
4491c4421ceaSFande Kong   PetscInt  i;
4492c4421ceaSFande Kong   PetscBool identical;
4493c4421ceaSFande Kong 
4494c4421ceaSFande Kong   PetscFunctionBegin;
4495c4421ceaSFande Kong   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4496c4421ceaSFande Kong   for (i = 0; i < snes->numberreasonviews; i++) {
44979566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical));
44983ba16761SJacob Faibussowitsch     if (identical) PetscFunctionReturn(PETSC_SUCCESS);
4499c4421ceaSFande Kong   }
45005f80ce2aSJacob Faibussowitsch   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set");
4501c4421ceaSFande Kong   snes->reasonview[snes->numberreasonviews]          = f;
4502c4421ceaSFande Kong   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4503c4421ceaSFande Kong   snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx;
45043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4505c4421ceaSFande Kong }
4506c4421ceaSFande Kong 
450791f3e32bSBarry Smith /*@
4508f6dfbefdSBarry Smith   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed.
4509c4421ceaSFande Kong                                        All the user-provided convergedReasonView routines will be involved as well, if they exist.
45102a359c20SBarry Smith 
4511c3339decSBarry Smith   Collective
45122a359c20SBarry Smith 
45132a359c20SBarry Smith   Input Parameters:
4514f6dfbefdSBarry Smith . snes   - the `SNES` object
45152a359c20SBarry Smith 
4516f6dfbefdSBarry Smith   Level: advanced
45172a359c20SBarry Smith 
4518f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`,
4519f6dfbefdSBarry Smith           `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
45202a359c20SBarry Smith @*/
4521d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
4522d71ae5a4SJacob Faibussowitsch {
45232a359c20SBarry Smith   PetscViewer       viewer;
45242a359c20SBarry Smith   PetscBool         flg;
45252a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
45262a359c20SBarry Smith   PetscViewerFormat format;
4527c4421ceaSFande Kong   PetscInt          i;
45282a359c20SBarry Smith 
45292a359c20SBarry Smith   PetscFunctionBegin;
45303ba16761SJacob Faibussowitsch   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
45312a359c20SBarry Smith   incall = PETSC_TRUE;
4532c4421ceaSFande Kong 
4533c4421ceaSFande Kong   /* All user-provided viewers are called first, if they exist. */
453448a46eb9SPierre Jolivet   for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i]));
4535c4421ceaSFande Kong 
4536c4421ceaSFande Kong   /* Call PETSc default routine if users ask for it */
45379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg));
45382a359c20SBarry Smith   if (flg) {
45399566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
45409566063dSJacob Faibussowitsch     PetscCall(SNESConvergedReasonView(snes, viewer));
45419566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
45429566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
45432a359c20SBarry Smith   }
45442a359c20SBarry Smith   incall = PETSC_FALSE;
45453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
45462a359c20SBarry Smith }
45472a359c20SBarry Smith 
4548487a658cSBarry Smith /*@
4549f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
4550f6dfbefdSBarry Smith    Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`.
45519b94acceSBarry Smith 
4552c3339decSBarry Smith    Collective
4553c7afd0dbSLois Curfman McInnes 
4554b2002411SLois Curfman McInnes    Input Parameters:
4555f6dfbefdSBarry Smith +  snes - the `SNES` context
45560298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
455785385478SLisandro Dalcin -  x - the solution vector.
45589b94acceSBarry Smith 
4559f6dfbefdSBarry Smith    Note:
45608ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
4561f6dfbefdSBarry Smith    for the nonlinear solve prior to calling `SNESSolve()`.  In particular,
45628ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
4563f6dfbefdSBarry Smith    this vector to zero by calling `VecSet()`.
45648ddd3da0SLois Curfman McInnes 
456536851e7fSLois Curfman McInnes    Level: beginner
456636851e7fSLois Curfman McInnes 
4567f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4568db781477SPatrick Sanan           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4569db781477SPatrick Sanan           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`
45709b94acceSBarry Smith @*/
4571d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x)
4572d71ae5a4SJacob Faibussowitsch {
4573ace3abfcSBarry Smith   PetscBool flg;
4574efd51863SBarry Smith   PetscInt  grid;
45750298fd71SBarry Smith   Vec       xcreated = NULL;
4576caa4e7f2SJed Brown   DM        dm;
4577052efed2SBarry Smith 
45783a40ed3dSBarry Smith   PetscFunctionBegin;
45790700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4580a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3);
4581a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes, 1, x, 3);
45820700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2);
458385385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes, 1, b, 2);
458485385478SLisandro Dalcin 
458534b4d3a8SMatthew G. Knepley   /* High level operations using the nonlinear solver */
458606fc46c8SMatthew G. Knepley   {
458706fc46c8SMatthew G. Knepley     PetscViewer       viewer;
458806fc46c8SMatthew G. Knepley     PetscViewerFormat format;
45897c88af5aSMatthew G. Knepley     PetscInt          num;
459006fc46c8SMatthew G. Knepley     PetscBool         flg;
459106fc46c8SMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
459206fc46c8SMatthew G. Knepley 
459306fc46c8SMatthew G. Knepley     if (!incall) {
459434b4d3a8SMatthew G. Knepley       /* Estimate the convergence rate of the discretization */
45959566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
459606fc46c8SMatthew G. Knepley       if (flg) {
459706fc46c8SMatthew G. Knepley         PetscConvEst conv;
459846079b62SMatthew G. Knepley         DM           dm;
459946079b62SMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
460046079b62SMatthew G. Knepley         PetscInt     Nf;
460106fc46c8SMatthew G. Knepley 
460206fc46c8SMatthew G. Knepley         incall = PETSC_TRUE;
46039566063dSJacob Faibussowitsch         PetscCall(SNESGetDM(snes, &dm));
46049566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
46059566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(Nf, &alpha));
46069566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv));
46079566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes));
46089566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
46099566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
46109566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
46119566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
46129566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
46139566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
46149566063dSJacob Faibussowitsch         PetscCall(PetscViewerDestroy(&viewer));
46159566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
46169566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
461706fc46c8SMatthew G. Knepley         incall = PETSC_FALSE;
461806fc46c8SMatthew G. Knepley       }
461934b4d3a8SMatthew G. Knepley       /* Adaptively refine the initial grid */
4620b2588ea6SMatthew G. Knepley       num = 1;
46219566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg));
462234b4d3a8SMatthew G. Knepley       if (flg) {
462334b4d3a8SMatthew G. Knepley         DMAdaptor adaptor;
462434b4d3a8SMatthew G. Knepley 
462534b4d3a8SMatthew G. Knepley         incall = PETSC_TRUE;
46269566063dSJacob Faibussowitsch         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
46279566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSolver(adaptor, snes));
46289566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
46299566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetFromOptions(adaptor));
46309566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetUp(adaptor));
46319566063dSJacob Faibussowitsch         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
46329566063dSJacob Faibussowitsch         PetscCall(DMAdaptorDestroy(&adaptor));
463334b4d3a8SMatthew G. Knepley         incall = PETSC_FALSE;
463434b4d3a8SMatthew G. Knepley       }
46357c88af5aSMatthew G. Knepley       /* Use grid sequencing to adapt */
46367c88af5aSMatthew G. Knepley       num = 0;
46379566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL));
46387c88af5aSMatthew G. Knepley       if (num) {
46397c88af5aSMatthew G. Knepley         DMAdaptor adaptor;
46407c88af5aSMatthew G. Knepley 
46417c88af5aSMatthew G. Knepley         incall = PETSC_TRUE;
46429566063dSJacob Faibussowitsch         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
46439566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSolver(adaptor, snes));
46449566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
46459566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetFromOptions(adaptor));
46469566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetUp(adaptor));
46479566063dSJacob Faibussowitsch         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
46489566063dSJacob Faibussowitsch         PetscCall(DMAdaptorDestroy(&adaptor));
46497c88af5aSMatthew G. Knepley         incall = PETSC_FALSE;
46507c88af5aSMatthew G. Knepley       }
465106fc46c8SMatthew G. Knepley     }
465206fc46c8SMatthew G. Knepley   }
4653ad540459SPierre Jolivet   if (!x) x = snes->vec_sol;
4654caa4e7f2SJed Brown   if (!x) {
46559566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
46569566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(dm, &xcreated));
4657a69afd8bSBarry Smith     x = xcreated;
4658a69afd8bSBarry Smith   }
46599566063dSJacob Faibussowitsch   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre"));
4660f05ece33SBarry Smith 
46619566063dSJacob Faibussowitsch   for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4662efd51863SBarry Smith   for (grid = 0; grid < snes->gridsequence + 1; grid++) {
466385385478SLisandro Dalcin     /* set solution vector */
46649566063dSJacob Faibussowitsch     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
46659566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_sol));
466685385478SLisandro Dalcin     snes->vec_sol = x;
46679566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes, &dm));
4668caa4e7f2SJed Brown 
4669caa4e7f2SJed Brown     /* set affine vector if provided */
46709566063dSJacob Faibussowitsch     if (b) PetscCall(PetscObjectReference((PetscObject)b));
46719566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_rhs));
467285385478SLisandro Dalcin     snes->vec_rhs = b;
467385385478SLisandro Dalcin 
46745f80ce2aSJacob 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");
46755f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector");
46765f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector");
46774dfa11a4SJacob Faibussowitsch     if (!snes->vec_sol_update /* && snes->vec_sol */) { PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); }
46789566063dSJacob Faibussowitsch     PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol));
46799566063dSJacob Faibussowitsch     PetscCall(SNESSetUp(snes));
46803f149594SLisandro Dalcin 
46817eee914bSBarry Smith     if (!grid) {
468225e27a38SBarry Smith       if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP));
4683dd568438SSatish Balay     }
4684d25893d9SBarry Smith 
4685abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
46869371c9d4SSatish Balay     if (snes->counters_reset) {
46879371c9d4SSatish Balay       snes->nfuncs      = 0;
46889371c9d4SSatish Balay       snes->linear_its  = 0;
46899371c9d4SSatish Balay       snes->numFailures = 0;
46909371c9d4SSatish Balay     }
4691d5e45103SBarry Smith 
46929566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0));
4693dbbe0bcdSBarry Smith     PetscUseTypeMethod(snes, solve);
46949566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0));
46955f80ce2aSJacob Faibussowitsch     PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason");
4696422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
46973f149594SLisandro Dalcin 
469837ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
469937ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
470037ec4e1aSPeter Brune 
47019566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg));
47029566063dSJacob Faibussowitsch     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4703c4421ceaSFande Kong     /* Call converged reason views. This may involve user-provided viewers as well */
47049566063dSJacob Faibussowitsch     PetscCall(SNESConvergedReasonViewFromOptions(snes));
47055968eb51SBarry Smith 
47065f80ce2aSJacob Faibussowitsch     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged");
47079c8e83a9SBarry Smith     if (snes->reason < 0) break;
4708efd51863SBarry Smith     if (grid < snes->gridsequence) {
4709efd51863SBarry Smith       DM  fine;
4710efd51863SBarry Smith       Vec xnew;
4711efd51863SBarry Smith       Mat interp;
4712efd51863SBarry Smith 
47139566063dSJacob Faibussowitsch       PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine));
47145f80ce2aSJacob Faibussowitsch       PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing");
47159566063dSJacob Faibussowitsch       PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL));
47169566063dSJacob Faibussowitsch       PetscCall(DMCreateGlobalVector(fine, &xnew));
47179566063dSJacob Faibussowitsch       PetscCall(MatInterpolate(interp, x, xnew));
47189566063dSJacob Faibussowitsch       PetscCall(DMInterpolate(snes->dm, interp, fine));
47199566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&interp));
4720efd51863SBarry Smith       x = xnew;
4721efd51863SBarry Smith 
47229566063dSJacob Faibussowitsch       PetscCall(SNESReset(snes));
47239566063dSJacob Faibussowitsch       PetscCall(SNESSetDM(snes, fine));
47249566063dSJacob Faibussowitsch       PetscCall(SNESResetFromOptions(snes));
47259566063dSJacob Faibussowitsch       PetscCall(DMDestroy(&fine));
47269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4727efd51863SBarry Smith     }
4728efd51863SBarry Smith   }
47299566063dSJacob Faibussowitsch   PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view"));
47309566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution"));
47319566063dSJacob Faibussowitsch   PetscCall(DMMonitor(snes->dm));
47329566063dSJacob Faibussowitsch   PetscCall(SNESMonitorPauseFinal_Internal(snes));
47333f7e2da0SPeter Brune 
47349566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&xcreated));
47359566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
47363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
47379b94acceSBarry Smith }
47389b94acceSBarry Smith 
47399b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
47409b94acceSBarry Smith 
474182bf6240SBarry Smith /*@C
47424b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
47439b94acceSBarry Smith 
4744c3339decSBarry Smith    Collective
4745fee21e36SBarry Smith 
4746c7afd0dbSLois Curfman McInnes    Input Parameters:
4747f6dfbefdSBarry Smith +  snes - the `SNES` context
4748454a90a3SBarry Smith -  type - a known method
4749c7afd0dbSLois Curfman McInnes 
4750c7afd0dbSLois Curfman McInnes    Options Database Key:
4751454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
475204d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4753ae12b187SLois Curfman McInnes 
47549b94acceSBarry Smith    Notes:
4755e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
4756f6dfbefdSBarry Smith +    `SNESNEWTONLS` - Newton's method with line search
4757c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
4758f6dfbefdSBarry Smith -    `SNESNEWTONTRDC` - Newton's method with trust region
4759c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
47609b94acceSBarry Smith 
4761f6dfbefdSBarry Smith   Normally, it is best to use the `SNESSetFromOptions()` command and then
4762f6dfbefdSBarry Smith   set the `SNES` solver type from the options database rather than by using
4763ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4764ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4765f6dfbefdSBarry Smith   The `SNESSetType()` routine is provided for those situations where it
4766ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4767ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4768ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4769ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4770b0a32e0cSBarry Smith   appropriate method.
477136851e7fSLois Curfman McInnes 
4772f6dfbefdSBarry Smith     Developer Note:
4773f6dfbefdSBarry Smith     `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates
4774f6dfbefdSBarry Smith     the constructor in that list and calls it to create the specific object.
47758f6c3df8SBarry Smith 
477636851e7fSLois Curfman McInnes   Level: intermediate
4777a703fe33SLois Curfman McInnes 
4778f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
47799b94acceSBarry Smith @*/
4780d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type)
4781d71ae5a4SJacob Faibussowitsch {
4782ace3abfcSBarry Smith   PetscBool match;
47835f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(SNES);
47843a40ed3dSBarry Smith 
47853a40ed3dSBarry Smith   PetscFunctionBegin;
47860700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
47874482741eSBarry Smith   PetscValidCharPointer(type, 2);
478882bf6240SBarry Smith 
47899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match));
47903ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
479192ff6ae8SBarry Smith 
47929566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(SNESList, type, &r));
47935f80ce2aSJacob Faibussowitsch   PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type);
479475396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4795dbbe0bcdSBarry Smith   PetscTryTypeMethod(snes, destroy);
479675396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
47979e5d0892SLisandro Dalcin   snes->ops->setup          = NULL;
47989e5d0892SLisandro Dalcin   snes->ops->solve          = NULL;
47999e5d0892SLisandro Dalcin   snes->ops->view           = NULL;
48009e5d0892SLisandro Dalcin   snes->ops->setfromoptions = NULL;
48019e5d0892SLisandro Dalcin   snes->ops->destroy        = NULL;
48027fe760d5SStefano Zampini 
48037fe760d5SStefano Zampini   /* It may happen the user has customized the line search before calling SNESSetType */
48049566063dSJacob Faibussowitsch   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
48057fe760d5SStefano Zampini 
480675396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
480775396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4808f5af7f23SKarl Rupp 
48099566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type));
48109566063dSJacob Faibussowitsch   PetscCall((*r)(snes));
48113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48129b94acceSBarry Smith }
48139b94acceSBarry Smith 
48149b94acceSBarry Smith /*@C
4815f6dfbefdSBarry Smith    SNESGetType - Gets the `SNES` method type and name (as a string).
48169b94acceSBarry Smith 
4817c7afd0dbSLois Curfman McInnes    Not Collective
4818c7afd0dbSLois Curfman McInnes 
48199b94acceSBarry Smith    Input Parameter:
48204b0e389bSBarry Smith .  snes - nonlinear solver context
48219b94acceSBarry Smith 
48229b94acceSBarry Smith    Output Parameter:
4823f6dfbefdSBarry Smith .  type - `SNES` method (a character string)
48249b94acceSBarry Smith 
482536851e7fSLois Curfman McInnes    Level: intermediate
482636851e7fSLois Curfman McInnes 
4827f6dfbefdSBarry Smith .seealso: `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES`
48289b94acceSBarry Smith @*/
4829d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type)
4830d71ae5a4SJacob Faibussowitsch {
48313a40ed3dSBarry Smith   PetscFunctionBegin;
48320700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
48334482741eSBarry Smith   PetscValidPointer(type, 2);
48347adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
48353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48369b94acceSBarry Smith }
48379b94acceSBarry Smith 
48383cd8a7caSMatthew G. Knepley /*@
4839f6dfbefdSBarry Smith   SNESSetSolution - Sets the solution vector for use by the `SNES` routines.
48403cd8a7caSMatthew G. Knepley 
4841c3339decSBarry Smith   Logically Collective
48423cd8a7caSMatthew G. Knepley 
48433cd8a7caSMatthew G. Knepley   Input Parameters:
4844f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()`
48453cd8a7caSMatthew G. Knepley - u    - the solution vector
48463cd8a7caSMatthew G. Knepley 
48473cd8a7caSMatthew G. Knepley   Level: beginner
48483cd8a7caSMatthew G. Knepley 
4849f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec`
48503cd8a7caSMatthew G. Knepley @*/
4851d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u)
4852d71ae5a4SJacob Faibussowitsch {
48533cd8a7caSMatthew G. Knepley   DM dm;
48543cd8a7caSMatthew G. Knepley 
48553cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
48563cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
48573cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
48589566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)u));
48599566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol));
48603cd8a7caSMatthew G. Knepley 
48613cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
48623cd8a7caSMatthew G. Knepley 
48639566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
48649566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm, u));
48653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
48663cd8a7caSMatthew G. Knepley }
48673cd8a7caSMatthew G. Knepley 
486852baeb72SSatish Balay /*@
48699b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4870f6dfbefdSBarry Smith    stored. This is the fine grid solution when using `SNESSetGridSequence()`.
48719b94acceSBarry Smith 
4872f6dfbefdSBarry Smith    Not Collective, but x is parallel if snes is parallel
4873c7afd0dbSLois Curfman McInnes 
48749b94acceSBarry Smith    Input Parameter:
4875f6dfbefdSBarry Smith .  snes - the `SNES` context
48769b94acceSBarry Smith 
48779b94acceSBarry Smith    Output Parameter:
48789b94acceSBarry Smith .  x - the solution
48799b94acceSBarry Smith 
488070e92668SMatthew Knepley    Level: intermediate
488136851e7fSLois Curfman McInnes 
4882f6dfbefdSBarry Smith .seealso: `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()`
48839b94acceSBarry Smith @*/
4884d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x)
4885d71ae5a4SJacob Faibussowitsch {
48863a40ed3dSBarry Smith   PetscFunctionBegin;
48870700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
48884482741eSBarry Smith   PetscValidPointer(x, 2);
488985385478SLisandro Dalcin   *x = snes->vec_sol;
48903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
489170e92668SMatthew Knepley }
489270e92668SMatthew Knepley 
489352baeb72SSatish Balay /*@
48949b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
48959b94acceSBarry Smith    stored.
48969b94acceSBarry Smith 
4897f6dfbefdSBarry Smith    Not Collective, but x is parallel if snes is parallel
4898c7afd0dbSLois Curfman McInnes 
48999b94acceSBarry Smith    Input Parameter:
4900f6dfbefdSBarry Smith .  snes - the `SNES` context
49019b94acceSBarry Smith 
49029b94acceSBarry Smith    Output Parameter:
49039b94acceSBarry Smith .  x - the solution update
49049b94acceSBarry Smith 
490536851e7fSLois Curfman McInnes    Level: advanced
490636851e7fSLois Curfman McInnes 
4907f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()`
49089b94acceSBarry Smith @*/
4909d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x)
4910d71ae5a4SJacob Faibussowitsch {
49113a40ed3dSBarry Smith   PetscFunctionBegin;
49120700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
49134482741eSBarry Smith   PetscValidPointer(x, 2);
491485385478SLisandro Dalcin   *x = snes->vec_sol_update;
49153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
49169b94acceSBarry Smith }
49179b94acceSBarry Smith 
49189b94acceSBarry Smith /*@C
4919f6dfbefdSBarry Smith    SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()`
49209b94acceSBarry Smith 
4921f6dfbefdSBarry Smith    Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet.
4922c7afd0dbSLois Curfman McInnes 
49239b94acceSBarry Smith    Input Parameter:
4924f6dfbefdSBarry Smith .  snes - the `SNES` context
49259b94acceSBarry Smith 
4926d8d19677SJose E. Roman    Output Parameters:
49270298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4928f6dfbefdSBarry Smith .  f - the function (or NULL if you don't want it); see `SNESFunction` for calling sequence details
49290298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
49309b94acceSBarry Smith 
493136851e7fSLois Curfman McInnes    Level: advanced
493236851e7fSLois Curfman McInnes 
4933f6dfbefdSBarry Smith     Note:
4934f6dfbefdSBarry Smith    The vector r DOES NOT, in general, contain the current value of the `SNES` nonlinear function
493504edfde5SBarry Smith 
4936f6dfbefdSBarry Smith .seealso: `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction`
49379b94acceSBarry Smith @*/
4938d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
4939d71ae5a4SJacob Faibussowitsch {
49406cab3a1bSJed Brown   DM dm;
4941a63bb30eSJed Brown 
49423a40ed3dSBarry Smith   PetscFunctionBegin;
49430700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4944a63bb30eSJed Brown   if (r) {
4945a63bb30eSJed Brown     if (!snes->vec_func) {
4946a63bb30eSJed Brown       if (snes->vec_rhs) {
49479566063dSJacob Faibussowitsch         PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func));
4948a63bb30eSJed Brown       } else if (snes->vec_sol) {
49499566063dSJacob Faibussowitsch         PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func));
4950a63bb30eSJed Brown       } else if (snes->dm) {
49519566063dSJacob Faibussowitsch         PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func));
4952a63bb30eSJed Brown       }
4953a63bb30eSJed Brown     }
4954a63bb30eSJed Brown     *r = snes->vec_func;
4955a63bb30eSJed Brown   }
49569566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
49579566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm, f, ctx));
49583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
49599b94acceSBarry Smith }
49609b94acceSBarry Smith 
4961c79ef259SPeter Brune /*@C
4962f6dfbefdSBarry Smith    SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()`
4963c79ef259SPeter Brune 
4964c79ef259SPeter Brune    Input Parameter:
4965f6dfbefdSBarry Smith .  snes - the `SNES` context
4966c79ef259SPeter Brune 
4967d8d19677SJose E. Roman    Output Parameters:
4968f6dfbefdSBarry Smith +  f - the function (or NULL) see `SNESNGSFunction` for details
49690298fd71SBarry Smith -  ctx    - the function context (or NULL)
4970c79ef259SPeter Brune 
4971c79ef259SPeter Brune    Level: advanced
4972c79ef259SPeter Brune 
4973db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()`
4974c79ef259SPeter Brune @*/
4975c79ef259SPeter Brune 
4976d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx)
4977d71ae5a4SJacob Faibussowitsch {
49786cab3a1bSJed Brown   DM dm;
49796cab3a1bSJed Brown 
4980646217ecSPeter Brune   PetscFunctionBegin;
4981646217ecSPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
49829566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
49839566063dSJacob Faibussowitsch   PetscCall(DMSNESGetNGS(dm, f, ctx));
49843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4985646217ecSPeter Brune }
4986646217ecSPeter Brune 
49873c7409f5SSatish Balay /*@C
49883c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4989f6dfbefdSBarry Smith    `SNES` options in the database.
49903c7409f5SSatish Balay 
4991c3339decSBarry Smith    Logically Collective
4992fee21e36SBarry Smith 
4993d8d19677SJose E. Roman    Input Parameters:
4994f6dfbefdSBarry Smith +  snes - the `SNES` context
4995c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4996c7afd0dbSLois Curfman McInnes 
4997f6dfbefdSBarry Smith    Note:
4998a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4999c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
5000d850072dSLois Curfman McInnes 
500136851e7fSLois Curfman McInnes    Level: advanced
500236851e7fSLois Curfman McInnes 
5003f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()`
50043c7409f5SSatish Balay @*/
5005d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[])
5006d71ae5a4SJacob Faibussowitsch {
50073a40ed3dSBarry Smith   PetscFunctionBegin;
50080700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
50099566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix));
50109566063dSJacob Faibussowitsch   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
501135f5d045SPeter Brune   if (snes->linesearch) {
50129566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
50139566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix));
501435f5d045SPeter Brune   }
50159566063dSJacob Faibussowitsch   PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix));
50163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50173c7409f5SSatish Balay }
50183c7409f5SSatish Balay 
50193c7409f5SSatish Balay /*@C
5020f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
5021f6dfbefdSBarry Smith    `SNES` options in the database.
50223c7409f5SSatish Balay 
5023c3339decSBarry Smith    Logically Collective
5024fee21e36SBarry Smith 
5025c7afd0dbSLois Curfman McInnes    Input Parameters:
5026f6dfbefdSBarry Smith +  snes - the `SNES` context
5027c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
5028c7afd0dbSLois Curfman McInnes 
5029f6dfbefdSBarry Smith    Note:
5030a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
5031c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
5032d850072dSLois Curfman McInnes 
503336851e7fSLois Curfman McInnes    Level: advanced
503436851e7fSLois Curfman McInnes 
5035f6dfbefdSBarry Smith .seealso: `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()`
50363c7409f5SSatish Balay @*/
5037d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[])
5038d71ae5a4SJacob Faibussowitsch {
50393a40ed3dSBarry Smith   PetscFunctionBegin;
50400700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
50419566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix));
50429566063dSJacob Faibussowitsch   if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp));
504335f5d045SPeter Brune   if (snes->linesearch) {
50449566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
50459566063dSJacob Faibussowitsch     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix));
504635f5d045SPeter Brune   }
50479566063dSJacob Faibussowitsch   PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix));
50483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50493c7409f5SSatish Balay }
50503c7409f5SSatish Balay 
50519ab63eb5SSatish Balay /*@C
5052f6dfbefdSBarry Smith    SNESGetOptionsPrefix - Gets the prefix used for searching for all
5053f6dfbefdSBarry Smith    `SNES` options in the database.
50543c7409f5SSatish Balay 
5055c7afd0dbSLois Curfman McInnes    Not Collective
5056c7afd0dbSLois Curfman McInnes 
50573c7409f5SSatish Balay    Input Parameter:
5058f6dfbefdSBarry Smith .  snes - the `SNES` context
50593c7409f5SSatish Balay 
50603c7409f5SSatish Balay    Output Parameter:
50613c7409f5SSatish Balay .  prefix - pointer to the prefix string used
50623c7409f5SSatish Balay 
5063f6dfbefdSBarry Smith    Fortran Note:
506495452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
50659ab63eb5SSatish Balay    sufficient length to hold the prefix.
50669ab63eb5SSatish Balay 
506736851e7fSLois Curfman McInnes    Level: advanced
506836851e7fSLois Curfman McInnes 
5069f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()`
50703c7409f5SSatish Balay @*/
5071d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[])
5072d71ae5a4SJacob Faibussowitsch {
50733a40ed3dSBarry Smith   PetscFunctionBegin;
50740700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
50759566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix));
50763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
50773c7409f5SSatish Balay }
50783c7409f5SSatish Balay 
50793cea93caSBarry Smith /*@C
50801c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
50811c84c290SBarry Smith 
50821c84c290SBarry Smith    Not collective
50831c84c290SBarry Smith 
50841c84c290SBarry Smith    Input Parameters:
50851c84c290SBarry Smith +  name_solver - name of a new user-defined solver
50861c84c290SBarry Smith -  routine_create - routine to create method context
50871c84c290SBarry Smith 
5088f6dfbefdSBarry Smith    Note:
5089f6dfbefdSBarry Smith    `SNESRegister()` may be called multiple times to add several user-defined solvers.
50901c84c290SBarry Smith 
50911c84c290SBarry Smith    Sample usage:
50921c84c290SBarry Smith .vb
5093bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
50941c84c290SBarry Smith .ve
50951c84c290SBarry Smith 
50961c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
50971c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
50981c84c290SBarry Smith    or at runtime via the option
50991c84c290SBarry Smith $     -snes_type my_solver
51001c84c290SBarry Smith 
51011c84c290SBarry Smith    Level: advanced
51021c84c290SBarry Smith 
5103db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()`
51043cea93caSBarry Smith @*/
5105d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES))
5106d71ae5a4SJacob Faibussowitsch {
5107b2002411SLois Curfman McInnes   PetscFunctionBegin;
51089566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
51099566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&SNESList, sname, function));
51103ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5111b2002411SLois Curfman McInnes }
5112da9b6338SBarry Smith 
5113d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes)
5114d71ae5a4SJacob Faibussowitsch {
511577431f27SBarry Smith   PetscInt    N, i, j;
5116da9b6338SBarry Smith   Vec         u, uh, fh;
5117da9b6338SBarry Smith   PetscScalar value;
5118da9b6338SBarry Smith   PetscReal   norm;
5119da9b6338SBarry Smith 
5120da9b6338SBarry Smith   PetscFunctionBegin;
51219566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes, &u));
51229566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &uh));
51239566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u, &fh));
5124da9b6338SBarry Smith 
5125da9b6338SBarry Smith   /* currently only works for sequential */
51269566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n"));
51279566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u, &N));
5128da9b6338SBarry Smith   for (i = 0; i < N; i++) {
51299566063dSJacob Faibussowitsch     PetscCall(VecCopy(u, uh));
513063a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i));
5131da9b6338SBarry Smith     for (j = -10; j < 11; j++) {
51328b49ba18SBarry Smith       value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0);
51339566063dSJacob Faibussowitsch       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
51349566063dSJacob Faibussowitsch       PetscCall(SNESComputeFunction(snes, uh, fh));
51359566063dSJacob Faibussowitsch       PetscCall(VecNorm(fh, NORM_2, &norm));
513663a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "       j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm));
5137da9b6338SBarry Smith       value = -value;
51389566063dSJacob Faibussowitsch       PetscCall(VecSetValue(uh, i, value, ADD_VALUES));
5139da9b6338SBarry Smith     }
5140da9b6338SBarry Smith   }
51419566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&uh));
51429566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&fh));
51433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5144da9b6338SBarry Smith }
514571f87433Sdalcinl 
514671f87433Sdalcinl /*@
5147f6dfbefdSBarry Smith    SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for
514871f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
514971f87433Sdalcinl    Newton method.
515071f87433Sdalcinl 
5151c3339decSBarry Smith    Logically Collective
515271f87433Sdalcinl 
515371f87433Sdalcinl    Input Parameters:
5154f6dfbefdSBarry Smith +  snes - `SNES` context
5155f6dfbefdSBarry Smith -  flag - `PETSC_TRUE` or `PETSC_FALSE`
515671f87433Sdalcinl 
5157f6dfbefdSBarry Smith     Options Database Keys:
515864ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
515964ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
516064ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
516164ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
516264ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
516364ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
516464ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
516564ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
516664ba62caSBarry Smith 
5167f6dfbefdSBarry Smith    Note:
5168f6dfbefdSBarry Smith    The default is to use a constant relative tolerance for
516971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
517071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
517171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
517271f87433Sdalcinl    solver.
517371f87433Sdalcinl 
517471f87433Sdalcinl    Level: advanced
517571f87433Sdalcinl 
517671f87433Sdalcinl    Reference:
5177f6dfbefdSBarry Smith .  - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996.
517871f87433Sdalcinl 
5179f6dfbefdSBarry Smith .seealso: `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
518071f87433Sdalcinl @*/
5181d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag)
5182d71ae5a4SJacob Faibussowitsch {
518371f87433Sdalcinl   PetscFunctionBegin;
51840700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5185acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes, flag, 2);
518671f87433Sdalcinl   snes->ksp_ewconv = flag;
51873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
518871f87433Sdalcinl }
518971f87433Sdalcinl 
519071f87433Sdalcinl /*@
5191f6dfbefdSBarry Smith    SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method
519271f87433Sdalcinl    for computing relative tolerance for linear solvers within an
519371f87433Sdalcinl    inexact Newton method.
519471f87433Sdalcinl 
519571f87433Sdalcinl    Not Collective
519671f87433Sdalcinl 
519771f87433Sdalcinl    Input Parameter:
5198f6dfbefdSBarry Smith .  snes - `SNES` context
519971f87433Sdalcinl 
520071f87433Sdalcinl    Output Parameter:
5201f6dfbefdSBarry Smith .  flag - `PETSC_TRUE` or `PETSC_FALSE`
520271f87433Sdalcinl 
520371f87433Sdalcinl    Level: advanced
520471f87433Sdalcinl 
5205db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
520671f87433Sdalcinl @*/
5207d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag)
5208d71ae5a4SJacob Faibussowitsch {
520971f87433Sdalcinl   PetscFunctionBegin;
52100700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5211534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag, 2);
521271f87433Sdalcinl   *flag = snes->ksp_ewconv;
52133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
521471f87433Sdalcinl }
521571f87433Sdalcinl 
521671f87433Sdalcinl /*@
5217fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
521871f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
521971f87433Sdalcinl    Newton method.
522071f87433Sdalcinl 
5221c3339decSBarry Smith    Logically Collective
522271f87433Sdalcinl 
522371f87433Sdalcinl    Input Parameters:
5224f6dfbefdSBarry Smith +    snes - `SNES` context
52250f0abf79SStefano Zampini .    version - version 1, 2 (default is 2), 3 or 4
522671f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
522771f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
522871f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
522971f87433Sdalcinl              (0 <= gamma2 <= 1)
523071f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
523171f87433Sdalcinl .    alpha2 - power for safeguard
523271f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
523371f87433Sdalcinl 
5234f6dfbefdSBarry Smith    Notes:
523571f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
523671f87433Sdalcinl 
5237f6dfbefdSBarry Smith    Use `PETSC_DEFAULT` to retain the default for any of the parameters.
523871f87433Sdalcinl 
523971f87433Sdalcinl    Level: advanced
524071f87433Sdalcinl 
5241f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
524271f87433Sdalcinl @*/
5243d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold)
5244d71ae5a4SJacob Faibussowitsch {
5245fa9f3622SBarry Smith   SNESKSPEW *kctx;
52465fd66863SKarl Rupp 
524771f87433Sdalcinl   PetscFunctionBegin;
52480700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5249fa9f3622SBarry Smith   kctx = (SNESKSPEW *)snes->kspconvctx;
52505f80ce2aSJacob Faibussowitsch   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
5251c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes, version, 2);
5252c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, rtol_0, 3);
5253c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, rtol_max, 4);
5254c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, gamma, 5);
5255c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, alpha, 6);
5256c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, alpha2, 7);
5257c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes, threshold, 8);
525871f87433Sdalcinl 
525971f87433Sdalcinl   if (version != PETSC_DEFAULT) kctx->version = version;
526071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
526171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max;
526271f87433Sdalcinl   if (gamma != PETSC_DEFAULT) kctx->gamma = gamma;
526371f87433Sdalcinl   if (alpha != PETSC_DEFAULT) kctx->alpha = alpha;
526471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2;
526571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
526671f87433Sdalcinl 
52670f0abf79SStefano 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);
52680b121fc5SBarry 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);
52690b121fc5SBarry 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);
52700b121fc5SBarry 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);
52710b121fc5SBarry 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);
52720b121fc5SBarry 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);
52733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
527471f87433Sdalcinl }
527571f87433Sdalcinl 
527671f87433Sdalcinl /*@
5277fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
527871f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
527971f87433Sdalcinl    Newton method.
528071f87433Sdalcinl 
528171f87433Sdalcinl    Not Collective
528271f87433Sdalcinl 
528397bb3fdcSJose E. Roman    Input Parameter:
5284f6dfbefdSBarry Smith .    snes - `SNES` context
528571f87433Sdalcinl 
528671f87433Sdalcinl    Output Parameters:
52870f0abf79SStefano Zampini +    version - version 1, 2 (default is 2), 3 or 4
528871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
528971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5290bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
529171f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
529271f87433Sdalcinl .    alpha2 - power for safeguard
529371f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
529471f87433Sdalcinl 
529571f87433Sdalcinl    Level: advanced
529671f87433Sdalcinl 
5297f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
529871f87433Sdalcinl @*/
5299d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold)
5300d71ae5a4SJacob Faibussowitsch {
5301fa9f3622SBarry Smith   SNESKSPEW *kctx;
53025fd66863SKarl Rupp 
530371f87433Sdalcinl   PetscFunctionBegin;
53040700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5305fa9f3622SBarry Smith   kctx = (SNESKSPEW *)snes->kspconvctx;
53065f80ce2aSJacob Faibussowitsch   PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing");
530771f87433Sdalcinl   if (version) *version = kctx->version;
530871f87433Sdalcinl   if (rtol_0) *rtol_0 = kctx->rtol_0;
530971f87433Sdalcinl   if (rtol_max) *rtol_max = kctx->rtol_max;
531071f87433Sdalcinl   if (gamma) *gamma = kctx->gamma;
531171f87433Sdalcinl   if (alpha) *alpha = kctx->alpha;
531271f87433Sdalcinl   if (alpha2) *alpha2 = kctx->alpha2;
531371f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
53143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
531571f87433Sdalcinl }
531671f87433Sdalcinl 
5317d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
5318d71ae5a4SJacob Faibussowitsch {
5319fa9f3622SBarry Smith   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
532071f87433Sdalcinl   PetscReal  rtol = PETSC_DEFAULT, stol;
532171f87433Sdalcinl 
532271f87433Sdalcinl   PetscFunctionBegin;
53233ba16761SJacob Faibussowitsch   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
532430058271SDmitry Karpeev   if (!snes->iter) {
532530058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
53269566063dSJacob Faibussowitsch     PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first));
53270f0abf79SStefano Zampini   } else {
53280fdf79fbSJacob Faibussowitsch     PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version);
532971f87433Sdalcinl     if (kctx->version == 1) {
53300f0abf79SStefano Zampini       rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last;
533185ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last, kctx->alpha2);
533271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
533371f87433Sdalcinl     } else if (kctx->version == 2) {
533485ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
533585ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
533671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol, stol);
533771f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
533885ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha);
533971f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
534085ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha);
534171f87433Sdalcinl       stol = PetscMax(rtol, stol);
534271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0, stol);
534371f87433Sdalcinl       /* safeguard: avoid oversolving */
534430058271SDmitry Karpeev       stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm;
534571f87433Sdalcinl       stol = PetscMax(rtol, stol);
534671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0, stol);
53470fdf79fbSJacob Faibussowitsch     } else /* if (kctx->version == 4) */ {
53480fdf79fbSJacob Faibussowitsch       /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
53490f0abf79SStefano Zampini       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
53500f0abf79SStefano Zampini       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
53510f0abf79SStefano Zampini       PetscReal rk   = ared / pred;
53520f0abf79SStefano Zampini       if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1;
53530f0abf79SStefano Zampini       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
53540f0abf79SStefano Zampini       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
53550f0abf79SStefano Zampini       else rtol = kctx->v4_m2 * kctx->rtol_last;
53560f0abf79SStefano Zampini 
53579371c9d4SSatish 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) {
53580f0abf79SStefano Zampini         rtol = kctx->v4_m4 * kctx->rtol_last;
53590f0abf79SStefano 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);
53600f0abf79SStefano Zampini       } else {
53610f0abf79SStefano 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);
536271f87433Sdalcinl       }
53630f0abf79SStefano Zampini       kctx->rtol_last_2 = kctx->rtol_last;
53640f0abf79SStefano Zampini       kctx->rk_last_2   = kctx->rk_last;
53650f0abf79SStefano Zampini       kctx->rk_last     = rk;
53660fdf79fbSJacob Faibussowitsch     }
53670f0abf79SStefano Zampini   }
53680f0abf79SStefano Zampini   /* safeguard: avoid rtol greater than rtol_max */
536971f87433Sdalcinl   rtol = PetscMin(rtol, kctx->rtol_max);
53709566063dSJacob Faibussowitsch   PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT));
537163a3b9bcSJacob Faibussowitsch   PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol));
53723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
537371f87433Sdalcinl }
537471f87433Sdalcinl 
5375d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
5376d71ae5a4SJacob Faibussowitsch {
5377fa9f3622SBarry Smith   SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
537871f87433Sdalcinl   PCSide     pcside;
537971f87433Sdalcinl   Vec        lres;
538071f87433Sdalcinl 
538171f87433Sdalcinl   PetscFunctionBegin;
53823ba16761SJacob Faibussowitsch   if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS);
53839566063dSJacob Faibussowitsch   PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL));
538471dbe336SPeter Brune   kctx->norm_last = snes->norm;
53850f0abf79SStefano Zampini   if (kctx->version == 1 || kctx->version == 4) {
53864f00ce20SMatthew G. Knepley     PC        pc;
53870f0abf79SStefano Zampini     PetscBool getRes;
53884f00ce20SMatthew G. Knepley 
53899566063dSJacob Faibussowitsch     PetscCall(KSPGetPC(ksp, &pc));
53900f0abf79SStefano Zampini     PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes));
53910f0abf79SStefano Zampini     if (!getRes) {
53920f0abf79SStefano Zampini       KSPNormType normtype;
53930f0abf79SStefano Zampini 
53940f0abf79SStefano Zampini       PetscCall(KSPGetNormType(ksp, &normtype));
53950f0abf79SStefano Zampini       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
53960f0abf79SStefano Zampini     }
53979566063dSJacob Faibussowitsch     PetscCall(KSPGetPCSide(ksp, &pcside));
53980f0abf79SStefano Zampini     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
53999566063dSJacob Faibussowitsch       PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last));
540071f87433Sdalcinl     } else {
540171f87433Sdalcinl       /* KSP residual is preconditioned residual */
540271f87433Sdalcinl       /* compute true linear residual norm */
54030f0abf79SStefano Zampini       Mat J;
54040f0abf79SStefano Zampini       PetscCall(KSPGetOperators(ksp, &J, NULL));
54059566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(b, &lres));
54060f0abf79SStefano Zampini       PetscCall(MatMult(J, x, lres));
54079566063dSJacob Faibussowitsch       PetscCall(VecAYPX(lres, -1.0, b));
54089566063dSJacob Faibussowitsch       PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last));
54099566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&lres));
541071f87433Sdalcinl     }
541171f87433Sdalcinl   }
54123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
541371f87433Sdalcinl }
541471f87433Sdalcinl 
5415d4211eb9SBarry Smith /*@
5416f6dfbefdSBarry Smith    SNESGetKSP - Returns the `KSP` context for a `SNES` solver.
5417d4211eb9SBarry Smith 
5418f6dfbefdSBarry Smith    Not Collective, but if snes is parallel, then ksp is parallel
5419d4211eb9SBarry Smith 
5420d4211eb9SBarry Smith    Input Parameter:
5421f6dfbefdSBarry Smith .  snes - the `SNES` context
5422d4211eb9SBarry Smith 
5423d4211eb9SBarry Smith    Output Parameter:
5424f6dfbefdSBarry Smith .  ksp - the `KSP` context
5425d4211eb9SBarry Smith 
5426d4211eb9SBarry Smith    Notes:
5427f6dfbefdSBarry Smith    The user can then directly manipulate the `KSP` context to set various
5428d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
5429f6dfbefdSBarry Smith    `PC` contexts as well.
5430f6dfbefdSBarry Smith 
5431f6dfbefdSBarry Smith    Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function
5432d4211eb9SBarry Smith 
5433d4211eb9SBarry Smith    Level: beginner
5434d4211eb9SBarry Smith 
5435f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5436d4211eb9SBarry Smith @*/
5437d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp)
5438d71ae5a4SJacob Faibussowitsch {
543971f87433Sdalcinl   PetscFunctionBegin;
5440d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5441d4211eb9SBarry Smith   PetscValidPointer(ksp, 2);
5442d4211eb9SBarry Smith 
5443d4211eb9SBarry Smith   if (!snes->ksp) {
54449566063dSJacob Faibussowitsch     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp));
54459566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1));
5446d4211eb9SBarry Smith 
54479566063dSJacob Faibussowitsch     PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes));
54489566063dSJacob Faibussowitsch     PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes));
5449a5c2985bSBarry Smith 
54509566063dSJacob Faibussowitsch     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
54519566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options));
5452d4211eb9SBarry Smith   }
5453d4211eb9SBarry Smith   *ksp = snes->ksp;
54543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
545571f87433Sdalcinl }
54566c699258SBarry Smith 
5457af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
54586c699258SBarry Smith /*@
5459f6dfbefdSBarry Smith    SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners
54606c699258SBarry Smith 
5461c3339decSBarry Smith    Logically Collective
54626c699258SBarry Smith 
54636c699258SBarry Smith    Input Parameters:
54642a808120SBarry Smith +  snes - the nonlinear solver context
54652a808120SBarry Smith -  dm - the dm, cannot be NULL
54666c699258SBarry Smith 
5467f6dfbefdSBarry Smith    Note:
5468f6dfbefdSBarry Smith    A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`,
5469f6dfbefdSBarry Smith    even when not using interfaces like `DMSNESSetFunction()`.  Use `DMClone()` to get a distinct `DM` when solving different
5470e03a659cSJed Brown    problems using the same function space.
5471e03a659cSJed Brown 
54726c699258SBarry Smith    Level: intermediate
54736c699258SBarry Smith 
5474f6dfbefdSBarry Smith .seealso: `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
54756c699258SBarry Smith @*/
5476d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm)
5477d71ae5a4SJacob Faibussowitsch {
5478345fed2cSBarry Smith   KSP    ksp;
5479942e3340SBarry Smith   DMSNES sdm;
54806c699258SBarry Smith 
54816c699258SBarry Smith   PetscFunctionBegin;
54820700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
54832a808120SBarry Smith   PetscValidHeaderSpecific(dm, DM_CLASSID, 2);
54849566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
5485942e3340SBarry Smith   if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */
548651f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
54879566063dSJacob Faibussowitsch       PetscCall(DMCopyDMSNES(snes->dm, dm));
54889566063dSJacob Faibussowitsch       PetscCall(DMGetDMSNES(snes->dm, &sdm));
5489f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
54906cab3a1bSJed Brown     }
54919566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes));
54929566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&snes->dm));
54936cab3a1bSJed Brown   }
54946c699258SBarry Smith   snes->dm     = dm;
5495116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
5496f5af7f23SKarl Rupp 
54979566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes, &ksp));
54989566063dSJacob Faibussowitsch   PetscCall(KSPSetDM(ksp, dm));
54999566063dSJacob Faibussowitsch   PetscCall(KSPSetDMActive(ksp, PETSC_FALSE));
5500efd4aadfSBarry Smith   if (snes->npc) {
55019566063dSJacob Faibussowitsch     PetscCall(SNESSetDM(snes->npc, snes->dm));
55029566063dSJacob Faibussowitsch     PetscCall(SNESSetNPCSide(snes, snes->npcside));
55032c155ee1SBarry Smith   }
55043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55056c699258SBarry Smith }
55066c699258SBarry Smith 
55076c699258SBarry Smith /*@
5508f6dfbefdSBarry Smith    SNESGetDM - Gets the `DM` that may be used by some preconditioners
55096c699258SBarry Smith 
5510f6dfbefdSBarry Smith    Not Collective but dm obtained is parallel on snes
55116c699258SBarry Smith 
55126c699258SBarry Smith    Input Parameter:
55136c699258SBarry Smith . snes - the preconditioner context
55146c699258SBarry Smith 
55156c699258SBarry Smith    Output Parameter:
55166c699258SBarry Smith .  dm - the dm
55176c699258SBarry Smith 
55186c699258SBarry Smith    Level: intermediate
55196c699258SBarry Smith 
5520f6dfbefdSBarry Smith .seealso: `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
55216c699258SBarry Smith @*/
5522d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm)
5523d71ae5a4SJacob Faibussowitsch {
55246c699258SBarry Smith   PetscFunctionBegin;
55250700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
55266cab3a1bSJed Brown   if (!snes->dm) {
55279566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm));
5528116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
55296cab3a1bSJed Brown   }
55306c699258SBarry Smith   *dm = snes->dm;
55313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
55326c699258SBarry Smith }
55330807856dSBarry Smith 
553431823bd8SMatthew G Knepley /*@
5535be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
553631823bd8SMatthew G Knepley 
5537c3339decSBarry Smith   Collective
553831823bd8SMatthew G Knepley 
553931823bd8SMatthew G Knepley   Input Parameters:
5540f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()`
5541f6dfbefdSBarry Smith - npc   - the preconditioner object
554231823bd8SMatthew G Knepley 
554331823bd8SMatthew G Knepley   Notes:
5544f6dfbefdSBarry Smith   Use `SNESGetNPC()` to retrieve the preconditioner context (for example,
554531823bd8SMatthew G Knepley   to configure it using the API).
554631823bd8SMatthew G Knepley 
5547f6dfbefdSBarry Smith   Only some `SNESType` can use a nonlinear preconditioner
5548f6dfbefdSBarry Smith 
554931823bd8SMatthew G Knepley   Level: developer
555031823bd8SMatthew G Knepley 
5551f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()`
555231823bd8SMatthew G Knepley @*/
5553d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc)
5554d71ae5a4SJacob Faibussowitsch {
555531823bd8SMatthew G Knepley   PetscFunctionBegin;
555631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5557f6dfbefdSBarry Smith   PetscValidHeaderSpecific(npc, SNES_CLASSID, 2);
5558f6dfbefdSBarry Smith   PetscCheckSameComm(snes, 1, npc, 2);
5559f6dfbefdSBarry Smith   PetscCall(PetscObjectReference((PetscObject)npc));
55609566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&snes->npc));
5561f6dfbefdSBarry Smith   snes->npc = npc;
55623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
556331823bd8SMatthew G Knepley }
556431823bd8SMatthew G Knepley 
556531823bd8SMatthew G Knepley /*@
5566f6dfbefdSBarry Smith   SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver.
556731823bd8SMatthew G Knepley 
5568f6dfbefdSBarry Smith   Not Collective; but any changes to the obtained the npc object must be applied collectively
556931823bd8SMatthew G Knepley 
557031823bd8SMatthew G Knepley   Input Parameter:
5571f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()`
557231823bd8SMatthew G Knepley 
557331823bd8SMatthew G Knepley   Output Parameter:
5574f6dfbefdSBarry Smith . npc - preconditioner context
557531823bd8SMatthew G Knepley 
5576f6dfbefdSBarry Smith   Options Database Key:
5577f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner
5578b5badacbSBarry Smith 
557995452b02SPatrick Sanan   Notes:
5580f6dfbefdSBarry Smith     If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created.
5581be95d8f1SBarry Smith 
5582f6dfbefdSBarry Smith     The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5583f6dfbefdSBarry Smith     `SNES`
5584951fe5abSBarry Smith 
558531823bd8SMatthew G Knepley   Level: developer
558631823bd8SMatthew G Knepley 
5587db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
558831823bd8SMatthew G Knepley @*/
5589d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
5590d71ae5a4SJacob Faibussowitsch {
5591a64e098fSPeter Brune   const char *optionsprefix;
559231823bd8SMatthew G Knepley 
559331823bd8SMatthew G Knepley   PetscFunctionBegin;
559431823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
559531823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
5596efd4aadfSBarry Smith   if (!snes->npc) {
55979566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc));
55989566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1));
55999566063dSJacob Faibussowitsch     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
56009566063dSJacob Faibussowitsch     PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix));
56019566063dSJacob Faibussowitsch     PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_"));
56029566063dSJacob Faibussowitsch     PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE));
560331823bd8SMatthew G Knepley   }
5604efd4aadfSBarry Smith   *pc = snes->npc;
56053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
560631823bd8SMatthew G Knepley }
560731823bd8SMatthew G Knepley 
56083ad1a0b9SPatrick Farrell /*@
56093ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
56103ad1a0b9SPatrick Farrell 
56113ad1a0b9SPatrick Farrell   Not Collective
56123ad1a0b9SPatrick Farrell 
56133ad1a0b9SPatrick Farrell   Input Parameter:
5614f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()`
56153ad1a0b9SPatrick Farrell 
56163ad1a0b9SPatrick Farrell   Output Parameter:
5617f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not
56183ad1a0b9SPatrick Farrell 
56193ad1a0b9SPatrick Farrell   Level: developer
56203ad1a0b9SPatrick Farrell 
5621db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()`
56223ad1a0b9SPatrick Farrell @*/
5623d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
5624d71ae5a4SJacob Faibussowitsch {
56253ad1a0b9SPatrick Farrell   PetscFunctionBegin;
56263ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5627efd4aadfSBarry Smith   *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE);
56283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
56293ad1a0b9SPatrick Farrell }
56303ad1a0b9SPatrick Farrell 
5631c40d0f55SPeter Brune /*@
5632be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5633c40d0f55SPeter Brune 
5634c3339decSBarry Smith     Logically Collective
5635c40d0f55SPeter Brune 
5636c40d0f55SPeter Brune     Input Parameter:
5637f6dfbefdSBarry Smith .   snes - iterative context obtained from `SNESCreate()`
5638c40d0f55SPeter Brune 
5639c40d0f55SPeter Brune     Output Parameter:
5640c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5641c40d0f55SPeter Brune .vb
56422d547940SBarry Smith       PC_LEFT - left preconditioning
56432d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5644c40d0f55SPeter Brune .ve
5645c40d0f55SPeter Brune 
5646f6dfbefdSBarry Smith     Options Database Key:
564767b8a455SSatish Balay .   -snes_npc_side <right,left> - nonlinear preconditioner side
5648c40d0f55SPeter Brune 
5649f6dfbefdSBarry Smith     Note:
5650f6dfbefdSBarry Smith     `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning.
56512d547940SBarry Smith 
5652c40d0f55SPeter Brune     Level: intermediate
5653c40d0f55SPeter Brune 
5654f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()`
5655c40d0f55SPeter Brune @*/
5656d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side)
5657d71ae5a4SJacob Faibussowitsch {
5658c40d0f55SPeter Brune   PetscFunctionBegin;
5659c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5660c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes, side, 2);
5661b552625fSStefano Zampini   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
566254c59aa7SJacob Faibussowitsch   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported");
5663efd4aadfSBarry Smith   snes->npcside = side;
56643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5665c40d0f55SPeter Brune }
5666c40d0f55SPeter Brune 
5667c40d0f55SPeter Brune /*@
5668be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5669c40d0f55SPeter Brune 
5670c40d0f55SPeter Brune     Not Collective
5671c40d0f55SPeter Brune 
5672c40d0f55SPeter Brune     Input Parameter:
5673f6dfbefdSBarry Smith .   snes - iterative context obtained from `SNESCreate()`
5674c40d0f55SPeter Brune 
5675c40d0f55SPeter Brune     Output Parameter:
5676c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5677c40d0f55SPeter Brune .vb
5678f6dfbefdSBarry Smith       `PC_LEFT` - left preconditioning
5679f6dfbefdSBarry Smith       `PC_RIGHT` - right preconditioning (default for most nonlinear solvers)
5680c40d0f55SPeter Brune .ve
5681c40d0f55SPeter Brune 
5682c40d0f55SPeter Brune     Level: intermediate
5683c40d0f55SPeter Brune 
5684f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()`
5685c40d0f55SPeter Brune @*/
5686d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side)
5687d71ae5a4SJacob Faibussowitsch {
5688c40d0f55SPeter Brune   PetscFunctionBegin;
5689c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5690c40d0f55SPeter Brune   PetscValidPointer(side, 2);
5691efd4aadfSBarry Smith   *side = snes->npcside;
56923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5693c40d0f55SPeter Brune }
5694c40d0f55SPeter Brune 
56959e764e56SPeter Brune /*@
5696f6dfbefdSBarry Smith   SNESSetLineSearch - Sets the linesearch on the `SNES` instance.
56979e764e56SPeter Brune 
5698c3339decSBarry Smith   Collective
56999e764e56SPeter Brune 
57009e764e56SPeter Brune   Input Parameters:
5701f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()`
57029e764e56SPeter Brune - linesearch   - the linesearch object
57039e764e56SPeter Brune 
5704f6dfbefdSBarry Smith   Note:
5705f6dfbefdSBarry Smith   Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example,
57069e764e56SPeter Brune   to configure it using the API).
57079e764e56SPeter Brune 
57089e764e56SPeter Brune   Level: developer
57099e764e56SPeter Brune 
5710db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`
57119e764e56SPeter Brune @*/
5712d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
5713d71ae5a4SJacob Faibussowitsch {
57149e764e56SPeter Brune   PetscFunctionBegin;
57159e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5716f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
57179e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
57189566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)linesearch));
57199566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5720f5af7f23SKarl Rupp 
57219e764e56SPeter Brune   snes->linesearch = linesearch;
5722f5af7f23SKarl Rupp 
57233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
57249e764e56SPeter Brune }
57259e764e56SPeter Brune 
5726a34ceb2aSJed Brown /*@
5727f6dfbefdSBarry Smith   SNESGetLineSearch - Returns a pointer to the line search context set with `SNESSetLineSearch()`
5728f6dfbefdSBarry Smith   or creates a default line search instance associated with the `SNES` and returns it.
57299e764e56SPeter Brune 
57309e764e56SPeter Brune   Not Collective
57319e764e56SPeter Brune 
57329e764e56SPeter Brune   Input Parameter:
5733f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()`
57349e764e56SPeter Brune 
57359e764e56SPeter Brune   Output Parameter:
57369e764e56SPeter Brune . linesearch - linesearch context
57379e764e56SPeter Brune 
5738162e0bf5SPeter Brune   Level: beginner
57399e764e56SPeter Brune 
5740f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()`
57419e764e56SPeter Brune @*/
5742d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
5743d71ae5a4SJacob Faibussowitsch {
57449e764e56SPeter Brune   const char *optionsprefix;
57459e764e56SPeter Brune 
57469e764e56SPeter Brune   PetscFunctionBegin;
57479e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
57489e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
57499e764e56SPeter Brune   if (!snes->linesearch) {
57509566063dSJacob Faibussowitsch     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
57519566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
57529566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
57539566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
57549566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1));
57559e764e56SPeter Brune   }
57569e764e56SPeter Brune   *linesearch = snes->linesearch;
57573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
57589e764e56SPeter Brune }
5759