xref: /petsc/src/snes/interface/snes.c (revision a958fbfc1c07da5d8abfa22584ccb9c44e85e9ad)
1af0996ceSBarry Smith #include <petsc/private/snesimpl.h>      /*I "petscsnes.h"  I*/
207475bc1SBarry Smith #include <petscdmshell.h>
3d96771aaSLisandro Dalcin #include <petscdraw.h>
4a01aa210SMatthew G. Knepley #include <petscds.h>
534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h>
606fc46c8SMatthew G. Knepley #include <petscconvest.h>
79b94acceSBarry Smith 
8ace3abfcSBarry Smith PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
90298fd71SBarry Smith PetscFunctionList SNESList              = NULL;
108ba1e511SMatthew Knepley 
118ba1e511SMatthew Knepley /* Logging support */
1222c6f798SBarry Smith PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
13e3ed9ee7SBarry Smith PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval;
14a09944afSBarry Smith 
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
2567b8a455SSatish Balay .  -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33db781477SPatrick Sanan .seealso: `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
34e113a28aSBarry Smith @*/
357087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
36e113a28aSBarry Smith {
37e113a28aSBarry Smith   PetscFunctionBegin;
38e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
40e113a28aSBarry Smith   snes->errorifnotconverged = flg;
41e113a28aSBarry Smith   PetscFunctionReturn(0);
42e113a28aSBarry Smith }
43e113a28aSBarry Smith 
44e113a28aSBarry Smith /*@
45e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
46e113a28aSBarry Smith 
47e113a28aSBarry Smith    Not Collective
48e113a28aSBarry Smith 
49e113a28aSBarry Smith    Input Parameter:
50e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Output Parameter:
53e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
54e113a28aSBarry Smith 
55e113a28aSBarry Smith    Level: intermediate
56e113a28aSBarry Smith 
57db781477SPatrick Sanan .seealso: `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()`
58e113a28aSBarry Smith @*/
597087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
60e113a28aSBarry Smith {
61e113a28aSBarry Smith   PetscFunctionBegin;
62e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
63534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag,2);
64e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
65e113a28aSBarry Smith   PetscFunctionReturn(0);
66e113a28aSBarry Smith }
67e113a28aSBarry Smith 
684fc747eaSLawrence Mitchell /*@
694fc747eaSLawrence Mitchell     SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
704fc747eaSLawrence Mitchell 
714fc747eaSLawrence Mitchell    Logically Collective on SNES
724fc747eaSLawrence Mitchell 
734fc747eaSLawrence Mitchell     Input Parameters:
744fc747eaSLawrence Mitchell +   snes - the shell SNES
754fc747eaSLawrence Mitchell -   flg - is the residual computed?
764fc747eaSLawrence Mitchell 
774fc747eaSLawrence Mitchell    Level: advanced
784fc747eaSLawrence Mitchell 
79db781477SPatrick Sanan .seealso: `SNESGetAlwaysComputesFinalResidual()`
804fc747eaSLawrence Mitchell @*/
814fc747eaSLawrence Mitchell PetscErrorCode  SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg)
824fc747eaSLawrence Mitchell {
834fc747eaSLawrence Mitchell   PetscFunctionBegin;
844fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
854fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = flg;
864fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
874fc747eaSLawrence Mitchell }
884fc747eaSLawrence Mitchell 
894fc747eaSLawrence Mitchell /*@
904fc747eaSLawrence Mitchell     SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution?
914fc747eaSLawrence Mitchell 
924fc747eaSLawrence Mitchell    Logically Collective on SNES
934fc747eaSLawrence Mitchell 
944fc747eaSLawrence Mitchell     Input Parameter:
954fc747eaSLawrence Mitchell .   snes - the shell SNES
964fc747eaSLawrence Mitchell 
974fc747eaSLawrence Mitchell     Output Parameter:
984fc747eaSLawrence Mitchell .   flg - is the residual computed?
994fc747eaSLawrence Mitchell 
1004fc747eaSLawrence Mitchell    Level: advanced
1014fc747eaSLawrence Mitchell 
102db781477SPatrick Sanan .seealso: `SNESSetAlwaysComputesFinalResidual()`
1034fc747eaSLawrence Mitchell @*/
1044fc747eaSLawrence Mitchell PetscErrorCode  SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg)
1054fc747eaSLawrence Mitchell {
1064fc747eaSLawrence Mitchell   PetscFunctionBegin;
1074fc747eaSLawrence Mitchell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1084fc747eaSLawrence Mitchell   *flg = snes->alwayscomputesfinalresidual;
1094fc747eaSLawrence Mitchell   PetscFunctionReturn(0);
1104fc747eaSLawrence Mitchell }
1114fc747eaSLawrence Mitchell 
112e725d27bSBarry Smith /*@
113bf388a1fSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
1144936397dSBarry Smith      in the functions domain. For example, negative pressure.
1154936397dSBarry Smith 
1163f9fe445SBarry Smith    Logically Collective on SNES
1174936397dSBarry Smith 
1184936397dSBarry Smith    Input Parameters:
1196a388c36SPeter Brune .  snes - the SNES context
1204936397dSBarry Smith 
12128529972SSatish Balay    Level: advanced
1224936397dSBarry Smith 
123db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`
1244936397dSBarry Smith @*/
1257087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1264936397dSBarry Smith {
1274936397dSBarry Smith   PetscFunctionBegin;
1280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1295f80ce2aSJacob Faibussowitsch   PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain");
1304936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1314936397dSBarry Smith   PetscFunctionReturn(0);
1324936397dSBarry Smith }
1334936397dSBarry Smith 
1346a388c36SPeter Brune /*@
13507b62357SFande Kong    SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense any more. For example there is a negative element transformation.
13607b62357SFande Kong 
13707b62357SFande Kong    Logically Collective on SNES
13807b62357SFande Kong 
13907b62357SFande Kong    Input Parameters:
14007b62357SFande Kong .  snes - the SNES context
14107b62357SFande Kong 
14207b62357SFande Kong    Level: advanced
14307b62357SFande Kong 
144db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`
14507b62357SFande Kong @*/
14607b62357SFande Kong PetscErrorCode SNESSetJacobianDomainError(SNES snes)
14707b62357SFande Kong {
14807b62357SFande Kong   PetscFunctionBegin;
14907b62357SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1505f80ce2aSJacob Faibussowitsch   PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates computeJacobian does not make sense");
15107b62357SFande Kong   snes->jacobiandomainerror = PETSC_TRUE;
15207b62357SFande Kong   PetscFunctionReturn(0);
15307b62357SFande Kong }
15407b62357SFande Kong 
15507b62357SFande Kong /*@
156b351a90bSFande Kong    SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error
157b351a90bSFande Kong    in the debug mode, and do not check it in the optimized mode.
158b351a90bSFande Kong 
159b351a90bSFande Kong    Logically Collective on SNES
160b351a90bSFande Kong 
161b351a90bSFande Kong    Input Parameters:
162a2b725a8SWilliam Gropp +  snes - the SNES context
163a2b725a8SWilliam Gropp -  flg  - indicates if or not to check jacobian domain error after each Jacobian evaluation
164b351a90bSFande Kong 
165b351a90bSFande Kong    Level: advanced
166b351a90bSFande Kong 
167db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()`
168b351a90bSFande Kong @*/
169b351a90bSFande Kong PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg)
170b351a90bSFande Kong {
171b351a90bSFande Kong   PetscFunctionBegin;
172b351a90bSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
173b351a90bSFande Kong   snes->checkjacdomainerror = flg;
174b351a90bSFande Kong   PetscFunctionReturn(0);
175b351a90bSFande Kong }
176b351a90bSFande Kong 
177b351a90bSFande Kong /*@
1788383d7d7SFande Kong    SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation.
1798383d7d7SFande Kong 
1808383d7d7SFande Kong    Logically Collective on SNES
1818383d7d7SFande Kong 
1828383d7d7SFande Kong    Input Parameters:
1838383d7d7SFande Kong .  snes - the SNES context
1848383d7d7SFande Kong 
1858383d7d7SFande Kong    Output Parameters:
1868383d7d7SFande Kong .  flg  - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation
1878383d7d7SFande Kong 
1888383d7d7SFande Kong    Level: advanced
1898383d7d7SFande Kong 
190db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()`
1918383d7d7SFande Kong @*/
1928383d7d7SFande Kong PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg)
1938383d7d7SFande Kong {
1948383d7d7SFande Kong   PetscFunctionBegin;
1958383d7d7SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
196534a8f05SLisandro Dalcin   PetscValidBoolPointer(flg,2);
1978383d7d7SFande Kong   *flg = snes->checkjacdomainerror;
1988383d7d7SFande Kong   PetscFunctionReturn(0);
1998383d7d7SFande Kong }
2008383d7d7SFande Kong 
2018383d7d7SFande Kong /*@
202c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
2036a388c36SPeter Brune 
2046a388c36SPeter Brune    Logically Collective on SNES
2056a388c36SPeter Brune 
2066a388c36SPeter Brune    Input Parameters:
2076a388c36SPeter Brune .  snes - the SNES context
2086a388c36SPeter Brune 
2096a388c36SPeter Brune    Output Parameters:
210bf388a1fSBarry Smith .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
2116a388c36SPeter Brune 
2126a388c36SPeter Brune    Level: advanced
2136a388c36SPeter Brune 
214db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`
2156a388c36SPeter Brune @*/
2166a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
2176a388c36SPeter Brune {
2186a388c36SPeter Brune   PetscFunctionBegin;
2196a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
220534a8f05SLisandro Dalcin   PetscValidBoolPointer(domainerror,2);
2216a388c36SPeter Brune   *domainerror = snes->domainerror;
2226a388c36SPeter Brune   PetscFunctionReturn(0);
2236a388c36SPeter Brune }
2246a388c36SPeter Brune 
22507b62357SFande Kong /*@
22607b62357SFande Kong    SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian;
22707b62357SFande Kong 
22807b62357SFande Kong    Logically Collective on SNES
22907b62357SFande Kong 
23007b62357SFande Kong    Input Parameters:
23107b62357SFande Kong .  snes - the SNES context
23207b62357SFande Kong 
23307b62357SFande Kong    Output Parameters:
23407b62357SFande Kong .  domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise.
23507b62357SFande Kong 
23607b62357SFande Kong    Level: advanced
23707b62357SFande Kong 
238c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()`
23907b62357SFande Kong @*/
24007b62357SFande Kong PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror)
24107b62357SFande Kong {
24207b62357SFande Kong   PetscFunctionBegin;
24307b62357SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
244534a8f05SLisandro Dalcin   PetscValidBoolPointer(domainerror,2);
24507b62357SFande Kong   *domainerror = snes->jacobiandomainerror;
24607b62357SFande Kong   PetscFunctionReturn(0);
24707b62357SFande Kong }
24807b62357SFande Kong 
24955849f57SBarry Smith /*@C
25055849f57SBarry Smith   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
25155849f57SBarry Smith 
25255849f57SBarry Smith   Collective on PetscViewer
25355849f57SBarry Smith 
25455849f57SBarry Smith   Input Parameters:
25555849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
25655849f57SBarry Smith            some related function before a call to SNESLoad().
25755849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
25855849f57SBarry Smith 
25955849f57SBarry Smith    Level: intermediate
26055849f57SBarry Smith 
26155849f57SBarry Smith   Notes:
26255849f57SBarry Smith    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
26355849f57SBarry Smith 
26455849f57SBarry Smith   Notes for advanced users:
26555849f57SBarry Smith   Most users should not need to know the details of the binary storage
26655849f57SBarry Smith   format, since SNESLoad() and TSView() completely hide these details.
26755849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
26855849f57SBarry Smith   format is
26955849f57SBarry Smith .vb
27055849f57SBarry Smith      has not yet been determined
27155849f57SBarry Smith .ve
27255849f57SBarry Smith 
273db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()`
27455849f57SBarry Smith @*/
2752d53ad75SBarry Smith PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
27655849f57SBarry Smith {
27755849f57SBarry Smith   PetscBool      isbinary;
278060da220SMatthew G. Knepley   PetscInt       classid;
27955849f57SBarry Smith   char           type[256];
28055849f57SBarry Smith   KSP            ksp;
2812d53ad75SBarry Smith   DM             dm;
2822d53ad75SBarry Smith   DMSNES         dmsnes;
28355849f57SBarry Smith 
28455849f57SBarry Smith   PetscFunctionBegin;
2852d53ad75SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28655849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
2879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
2885f80ce2aSJacob Faibussowitsch   PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
28955849f57SBarry Smith 
2909566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT));
2915f80ce2aSJacob Faibussowitsch   PetscCheck(classid == SNES_FILE_CLASSID,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
2929566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR));
2939566063dSJacob Faibussowitsch   PetscCall(SNESSetType(snes, type));
2942d53ad75SBarry Smith   if (snes->ops->load) {
2959566063dSJacob Faibussowitsch     PetscCall((*snes->ops->load)(snes,viewer));
296f2c2a1b9SBarry Smith   }
2979566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
2989566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&dmsnes));
2999566063dSJacob Faibussowitsch   PetscCall(DMSNESLoad(dmsnes,viewer));
3009566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,&ksp));
3019566063dSJacob Faibussowitsch   PetscCall(KSPLoad(ksp,viewer));
30255849f57SBarry Smith   PetscFunctionReturn(0);
30355849f57SBarry Smith }
3046a388c36SPeter Brune 
3059804daf3SBarry Smith #include <petscdraw.h>
306e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
307e04113cfSBarry Smith #include <petscviewersaws.h>
308bfb97211SBarry Smith #endif
3098404b7f3SBarry Smith 
310fe2efc57SMark /*@C
311fe2efc57SMark    SNESViewFromOptions - View from Options
312fe2efc57SMark 
313fe2efc57SMark    Collective on SNES
314fe2efc57SMark 
315fe2efc57SMark    Input Parameters:
316fe2efc57SMark +  A - the application ordering context
317736c3998SJose E. Roman .  obj - Optional object
318736c3998SJose E. Roman -  name - command line option
319fe2efc57SMark 
320fe2efc57SMark    Level: intermediate
321db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()`
322fe2efc57SMark @*/
323fe2efc57SMark PetscErrorCode  SNESViewFromOptions(SNES A,PetscObject obj,const char name[])
324fe2efc57SMark {
325fe2efc57SMark   PetscFunctionBegin;
326fe2efc57SMark   PetscValidHeaderSpecific(A,SNES_CLASSID,1);
3279566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
328fe2efc57SMark   PetscFunctionReturn(0);
329fe2efc57SMark }
330fe2efc57SMark 
331789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*);
332789d8953SBarry Smith 
3337e2c5f70SBarry Smith /*@C
3349b94acceSBarry Smith    SNESView - Prints the SNES data structure.
3359b94acceSBarry Smith 
3364c49b128SBarry Smith    Collective on SNES
337fee21e36SBarry Smith 
338c7afd0dbSLois Curfman McInnes    Input Parameters:
339c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
340c7afd0dbSLois Curfman McInnes -  viewer - visualization context
341c7afd0dbSLois Curfman McInnes 
3429b94acceSBarry Smith    Options Database Key:
343c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
3449b94acceSBarry Smith 
3459b94acceSBarry Smith    Notes:
3469b94acceSBarry Smith    The available visualization contexts include
347b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
348b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
349c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
350c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
351c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
3529b94acceSBarry Smith 
353052bf0daSPierre Jolivet    The available formats include
354052bf0daSPierre Jolivet +     PETSC_VIEWER_DEFAULT - standard output (default)
355052bf0daSPierre Jolivet -     PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM
356052bf0daSPierre Jolivet 
3573e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
358b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
3599b94acceSBarry Smith 
360595c91d4SBarry Smith   In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer).
361595c91d4SBarry Smith 
36236851e7fSLois Curfman McInnes    Level: beginner
36336851e7fSLois Curfman McInnes 
364db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`
3659b94acceSBarry Smith @*/
3667087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
3679b94acceSBarry Smith {
368fa9f3622SBarry Smith   SNESKSPEW      *kctx;
36994b7f48cSBarry Smith   KSP            ksp;
3707f1410a3SPeter Brune   SNESLineSearch linesearch;
37172a02f06SBarry Smith   PetscBool      iascii,isstring,isbinary,isdraw;
3722d53ad75SBarry Smith   DMSNES         dmsnes;
373e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
374536b137fSBarry Smith   PetscBool      issaws;
375bfb97211SBarry Smith #endif
3769b94acceSBarry Smith 
3773a40ed3dSBarry Smith   PetscFunctionBegin;
3780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3793050cee2SBarry Smith   if (!viewer) {
3809566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer));
3813050cee2SBarry Smith   }
3820700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
383c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
38474679c65SBarry Smith 
3859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
3869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring));
3879566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
3889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
389e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
3909566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws));
391bfb97211SBarry Smith #endif
39232077d6dSBarry Smith   if (iascii) {
393dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
3948404b7f3SBarry Smith     DM               dm;
3958404b7f3SBarry Smith     PetscErrorCode   (*cJ)(SNES,Vec,Mat,Mat,void*);
3968404b7f3SBarry Smith     void             *ctx;
397789d8953SBarry Smith     const char       *pre = "";
398dc0571f2SMatthew G. Knepley 
3999566063dSJacob Faibussowitsch     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer));
400fce1e034SJed Brown     if (!snes->setupcalled) {
4019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n"));
402fce1e034SJed Brown     }
403e7788613SBarry Smith     if (snes->ops->view) {
4049566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushTab(viewer));
4059566063dSJacob Faibussowitsch       PetscCall((*snes->ops->view)(snes,viewer));
4069566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(viewer));
4070ef38995SBarry Smith     }
40863a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n",snes->max_its,snes->max_funcs));
4099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol));
410efd4aadfSBarry Smith     if (snes->usesksp) {
41163a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%" PetscInt_FMT "\n",snes->linear_its));
412efd4aadfSBarry Smith     }
41363a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%" PetscInt_FMT "\n",snes->nfuncs));
4149566063dSJacob Faibussowitsch     PetscCall(SNESGetNormSchedule(snes, &normschedule));
4159566063dSJacob Faibussowitsch     if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]));
41617fe4bdfSPeter Brune     if (snes->gridsequence) {
41763a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%" PetscInt_FMT "\n",snes->gridsequence));
41817fe4bdfSPeter Brune     }
4199b94acceSBarry Smith     if (snes->ksp_ewconv) {
420fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
4219b94acceSBarry Smith       if (kctx) {
42263a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n",kctx->version));
4239566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"    rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold));
4249566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2));
4259b94acceSBarry Smith       }
4269b94acceSBarry Smith     }
427eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
4289566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n"));
429eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
43063a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n",snes->lagpreconditioner));
431eb1f6c34SBarry Smith     }
432eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
4339566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n"));
434eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
43563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n",snes->lagjacobian));
436eb1f6c34SBarry Smith     }
4379566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
4389566063dSJacob Faibussowitsch     PetscCall(DMSNESGetJacobian(dm,&cJ,&ctx));
439789d8953SBarry Smith     if (snes->mf_operator) {
4409566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing\n"));
441789d8953SBarry Smith       pre  = "Preconditioning ";
442789d8953SBarry Smith     }
4438404b7f3SBarry Smith     if (cJ == SNESComputeJacobianDefault) {
4449566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences one column at a time\n",pre));
4458404b7f3SBarry Smith     } else if (cJ == SNESComputeJacobianDefaultColor) {
4469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences with coloring\n",pre));
447789d8953SBarry Smith     /* it slightly breaks data encapsulation for access the DMDA information directly */
448789d8953SBarry Smith     } else if (cJ == SNESComputeJacobian_DMDA) {
449789d8953SBarry Smith       MatFDColoring fdcoloring;
4509566063dSJacob Faibussowitsch       PetscCall(PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring));
451789d8953SBarry Smith       if (fdcoloring) {
4529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using colored finite differences on a DMDA\n",pre));
453789d8953SBarry Smith       } else {
4549566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using a DMDA local Jacobian\n",pre));
455789d8953SBarry Smith       }
456789d8953SBarry Smith     } else if (snes->mf) {
4579566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing, no explicit Jacobian\n"));
4588404b7f3SBarry Smith     }
4590f5bd95cSBarry Smith   } else if (isstring) {
460317d6ea6SBarry Smith     const char *type;
4619566063dSJacob Faibussowitsch     PetscCall(SNESGetType(snes,&type));
4629566063dSJacob Faibussowitsch     PetscCall(PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type));
4639566063dSJacob Faibussowitsch     if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer));
46455849f57SBarry Smith   } else if (isbinary) {
46555849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
46655849f57SBarry Smith     MPI_Comm    comm;
46755849f57SBarry Smith     PetscMPIInt rank;
46855849f57SBarry Smith     char        type[256];
46955849f57SBarry Smith 
4709566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)snes,&comm));
4719566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(comm,&rank));
472dd400576SPatrick Sanan     if (rank == 0) {
4739566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT));
4749566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type)));
4759566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR));
47655849f57SBarry Smith     }
47755849f57SBarry Smith     if (snes->ops->view) {
4789566063dSJacob Faibussowitsch       PetscCall((*snes->ops->view)(snes,viewer));
47955849f57SBarry Smith     }
48072a02f06SBarry Smith   } else if (isdraw) {
48172a02f06SBarry Smith     PetscDraw draw;
48272a02f06SBarry Smith     char      str[36];
48389fd9fafSBarry Smith     PetscReal x,y,bottom,h;
48472a02f06SBarry Smith 
4859566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
4869566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetCurrentPoint(draw,&x,&y));
4879566063dSJacob Faibussowitsch     PetscCall(PetscStrncpy(str,"SNES: ",sizeof(str)));
4889566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str)));
4899566063dSJacob Faibussowitsch     PetscCall(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h));
49089fd9fafSBarry Smith     bottom = y - h;
4919566063dSJacob Faibussowitsch     PetscCall(PetscDrawPushCurrentPoint(draw,x,bottom));
492c4646bacSPeter Brune     if (snes->ops->view) {
4939566063dSJacob Faibussowitsch       PetscCall((*snes->ops->view)(snes,viewer));
494c4646bacSPeter Brune     }
495e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
496536b137fSBarry Smith   } else if (issaws) {
497d45a07a7SBarry Smith     PetscMPIInt rank;
4982657e9d9SBarry Smith     const char *name;
499d45a07a7SBarry Smith 
5009566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetName((PetscObject)snes,&name));
5019566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank));
502dd400576SPatrick Sanan     if (!((PetscObject)snes)->amsmem && rank == 0) {
503d45a07a7SBarry Smith       char       dir[1024];
504d45a07a7SBarry Smith 
5059566063dSJacob Faibussowitsch       PetscCall(PetscObjectViewSAWs((PetscObject)snes,viewer));
5069566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name));
5072657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
508bfb97211SBarry Smith       if (!snes->conv_hist) {
5099566063dSJacob Faibussowitsch         PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE));
510bfb97211SBarry Smith       }
5119566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name));
5122657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
513f05ece33SBarry Smith     }
514bfb97211SBarry Smith #endif
51572a02f06SBarry Smith   }
51672a02f06SBarry Smith   if (snes->linesearch) {
5179566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &linesearch));
5189566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5199566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchView(linesearch, viewer));
5209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
52119bcc07fSBarry Smith   }
522efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
5239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5249566063dSJacob Faibussowitsch     PetscCall(SNESView(snes->npc, viewer));
5259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
5264a0c5b0cSMatthew G Knepley   }
5279566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushTab(viewer));
5289566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(snes->dm,&dmsnes));
5299566063dSJacob Faibussowitsch   PetscCall(DMSNESView(dmsnes, viewer));
5309566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopTab(viewer));
5312c155ee1SBarry Smith   if (snes->usesksp) {
5329566063dSJacob Faibussowitsch     PetscCall(SNESGetKSP(snes,&ksp));
5339566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPushTab(viewer));
5349566063dSJacob Faibussowitsch     PetscCall(KSPView(ksp,viewer));
5359566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPopTab(viewer));
5362c155ee1SBarry Smith   }
53772a02f06SBarry Smith   if (isdraw) {
53872a02f06SBarry Smith     PetscDraw draw;
5399566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
5409566063dSJacob Faibussowitsch     PetscCall(PetscDrawPopCurrentPoint(draw));
5417f1410a3SPeter Brune   }
5423a40ed3dSBarry Smith   PetscFunctionReturn(0);
5439b94acceSBarry Smith }
5449b94acceSBarry Smith 
54576b2cf59SMatthew Knepley /*
54676b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
54776b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
54876b2cf59SMatthew Knepley */
54976b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
550a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
5516849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
55276b2cf59SMatthew Knepley 
553ac226902SBarry Smith /*@C
55476b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
55576b2cf59SMatthew Knepley 
55676b2cf59SMatthew Knepley   Not Collective
55776b2cf59SMatthew Knepley 
55876b2cf59SMatthew Knepley   Input Parameter:
55976b2cf59SMatthew Knepley . snescheck - function that checks for options
56076b2cf59SMatthew Knepley 
56176b2cf59SMatthew Knepley   Level: developer
56276b2cf59SMatthew Knepley 
563db781477SPatrick Sanan .seealso: `SNESSetFromOptions()`
56476b2cf59SMatthew Knepley @*/
5657087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
56676b2cf59SMatthew Knepley {
56776b2cf59SMatthew Knepley   PetscFunctionBegin;
56863a3b9bcSJacob Faibussowitsch   PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS);
56976b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
57076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
57176b2cf59SMatthew Knepley }
57276b2cf59SMatthew Knepley 
57325acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
574aa3661deSLisandro Dalcin 
575ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
576aa3661deSLisandro Dalcin {
577aa3661deSLisandro Dalcin   Mat            J;
578895c21f2SBarry Smith   MatNullSpace   nullsp;
579aa3661deSLisandro Dalcin 
580aa3661deSLisandro Dalcin   PetscFunctionBegin;
5810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
582aa3661deSLisandro Dalcin 
58398613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
58498613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
5859566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A ? A : B, NULL,&snes->vec_func));
58698613b67SLisandro Dalcin   }
58798613b67SLisandro Dalcin 
588aa3661deSLisandro Dalcin   if (version == 1) {
5899566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes,&J));
5909566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
5919566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
5921e2ae407SBarry Smith     /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */
593aa3661deSLisandro Dalcin   } else if (version == 2) {
5945f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_func,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
595570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
5969566063dSJacob Faibussowitsch     PetscCall(SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J));
597aa3661deSLisandro Dalcin #else
5982479783cSJose E. Roman     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)");
599aa3661deSLisandro Dalcin #endif
6002479783cSJose E. Roman   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2");
601aa3661deSLisandro Dalcin 
602895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
603895c21f2SBarry Smith   if (snes->jacobian) {
6049566063dSJacob Faibussowitsch     PetscCall(MatGetNullSpace(snes->jacobian,&nullsp));
605895c21f2SBarry Smith     if (nullsp) {
6069566063dSJacob Faibussowitsch       PetscCall(MatSetNullSpace(J,nullsp));
607895c21f2SBarry Smith     }
608895c21f2SBarry Smith   }
609895c21f2SBarry Smith 
61063a3b9bcSJacob Faibussowitsch   PetscCall(PetscInfo(snes,"Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version));
611d3462f78SMatthew Knepley   if (hasOperator) {
6123232da50SPeter Brune 
613aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
614aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
6159566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL));
616aa3661deSLisandro Dalcin   } else {
617aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
6183232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
619b552625fSStefano Zampini     if (snes->npcside == PC_LEFT && snes->npc) {
6209566063dSJacob Faibussowitsch       if (!snes->jacobian) PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL));
621172a4300SPeter Brune     } else {
622789d8953SBarry Smith       KSP       ksp;
623789d8953SBarry Smith       PC        pc;
624789d8953SBarry Smith       PetscBool match;
625789d8953SBarry Smith 
6269566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL));
627aa3661deSLisandro Dalcin       /* Force no preconditioner */
6289566063dSJacob Faibussowitsch       PetscCall(SNESGetKSP(snes,&ksp));
6299566063dSJacob Faibussowitsch       PetscCall(KSPGetPC(ksp,&pc));
6302698c518SLisandro Dalcin       PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&match,PCSHELL,PCH2OPUS,""));
631aa3661deSLisandro Dalcin       if (!match) {
6329566063dSJacob Faibussowitsch         PetscCall(PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n"));
6339566063dSJacob Faibussowitsch         PetscCall(PCSetType(pc,PCNONE));
634aa3661deSLisandro Dalcin       }
635aa3661deSLisandro Dalcin     }
636789d8953SBarry Smith   }
6379566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&J));
638aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
639aa3661deSLisandro Dalcin }
640aa3661deSLisandro Dalcin 
641dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
642dfe15315SJed Brown {
643dfe15315SJed Brown   SNES           snes = (SNES)ctx;
6440298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
645dfe15315SJed Brown 
646dfe15315SJed Brown   PetscFunctionBegin;
64716ebb321SJed Brown   if (PetscLogPrintInfo) {
64816ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
6499566063dSJacob Faibussowitsch     PetscCall(DMGetRefineLevel(dmfine,&finelevel));
6509566063dSJacob Faibussowitsch     PetscCall(DMGetCoarsenLevel(dmfine,&fineclevel));
6519566063dSJacob Faibussowitsch     PetscCall(DMGetRefineLevel(dmcoarse,&coarselevel));
6529566063dSJacob Faibussowitsch     PetscCall(DMGetCoarsenLevel(dmcoarse,&coarseclevel));
65363a3b9bcSJacob 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));
65416ebb321SJed Brown   }
655dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
656dfe15315SJed Brown   else {
6579566063dSJacob Faibussowitsch     PetscCall(DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named));
658dfe15315SJed Brown     Xfine = Xfine_named;
659dfe15315SJed Brown   }
6609566063dSJacob Faibussowitsch   PetscCall(DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse));
661907f5c5aSLawrence Mitchell   if (Inject) {
6629566063dSJacob Faibussowitsch     PetscCall(MatRestrict(Inject,Xfine,Xcoarse));
663907f5c5aSLawrence Mitchell   } else {
6649566063dSJacob Faibussowitsch     PetscCall(MatRestrict(Restrict,Xfine,Xcoarse));
6659566063dSJacob Faibussowitsch     PetscCall(VecPointwiseMult(Xcoarse,Xcoarse,Rscale));
666907f5c5aSLawrence Mitchell   }
6679566063dSJacob Faibussowitsch   PetscCall(DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse));
6689566063dSJacob Faibussowitsch   if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named));
669dfe15315SJed Brown   PetscFunctionReturn(0);
670dfe15315SJed Brown }
671dfe15315SJed Brown 
67216ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
67316ebb321SJed Brown {
67416ebb321SJed Brown   PetscFunctionBegin;
6759566063dSJacob Faibussowitsch   PetscCall(DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx));
67616ebb321SJed Brown   PetscFunctionReturn(0);
67716ebb321SJed Brown }
67816ebb321SJed Brown 
679a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
680a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
68123ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
682caa4e7f2SJed Brown {
683caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
6840298fd71SBarry Smith   Vec            X,Xnamed = NULL;
685dfe15315SJed Brown   DM             dmsave;
6864e269d77SPeter Brune   void           *ctxsave;
68725ce1634SJed Brown   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;
688caa4e7f2SJed Brown 
689caa4e7f2SJed Brown   PetscFunctionBegin;
690dfe15315SJed Brown   dmsave = snes->dm;
6919566063dSJacob Faibussowitsch   PetscCall(KSPGetDM(ksp,&snes->dm));
692dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
693dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
6949566063dSJacob Faibussowitsch     PetscCall(DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed));
695dfe15315SJed Brown     X    = Xnamed;
6969566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave));
6974e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
6988d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
6999566063dSJacob Faibussowitsch       PetscCall(SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL));
700dfe15315SJed Brown     }
7014e269d77SPeter Brune   }
7024dde8bb0SMatthew G. Knepley   /* Make sure KSP DM has the Jacobian computation routine */
7034dde8bb0SMatthew G. Knepley   {
7044dde8bb0SMatthew G. Knepley     DMSNES sdm;
7054e269d77SPeter Brune 
7069566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNES(snes->dm, &sdm));
7074dde8bb0SMatthew G. Knepley     if (!sdm->ops->computejacobian) {
7089566063dSJacob Faibussowitsch       PetscCall(DMCopyDMSNES(dmsave, snes->dm));
7094dde8bb0SMatthew G. Knepley     }
7104dde8bb0SMatthew G. Knepley   }
7112b93b426SMatthew G. Knepley   /* Compute the operators */
7129566063dSJacob Faibussowitsch   PetscCall(SNESComputeJacobian(snes,X,A,B));
7132b93b426SMatthew G. Knepley   /* Put the previous context back */
7148d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
7159566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,NULL,NULL,jac,ctxsave));
7164e269d77SPeter Brune   }
7174e269d77SPeter Brune 
7189566063dSJacob Faibussowitsch   if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed));
719dfe15315SJed Brown   snes->dm = dmsave;
720caa4e7f2SJed Brown   PetscFunctionReturn(0);
721caa4e7f2SJed Brown }
722caa4e7f2SJed Brown 
7236cab3a1bSJed Brown /*@
7246cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
7256cab3a1bSJed Brown 
7266cab3a1bSJed Brown    Collective
7276cab3a1bSJed Brown 
7284165533cSJose E. Roman    Input Parameter:
7296cab3a1bSJed Brown .  snes - snes to configure
7306cab3a1bSJed Brown 
7316cab3a1bSJed Brown    Level: developer
7326cab3a1bSJed Brown 
733db781477SPatrick Sanan .seealso: `SNESSetUp()`
7346cab3a1bSJed Brown @*/
7356cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
7366cab3a1bSJed Brown {
7376cab3a1bSJed Brown   DM             dm;
738942e3340SBarry Smith   DMSNES         sdm;
7396cab3a1bSJed Brown 
7406cab3a1bSJed Brown   PetscFunctionBegin;
7419566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
7429566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
74358b371f3SBarry Smith   if (!snes->jacobian && snes->mf) {
7446cab3a1bSJed Brown     Mat  J;
7456cab3a1bSJed Brown     void *functx;
7469566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes,&J));
7479566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
7489566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
7499566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
7509566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,J,J,NULL,NULL));
7519566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
752caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
7536cab3a1bSJed Brown     Mat J,B;
7549566063dSJacob Faibussowitsch     PetscCall(MatCreateSNESMF(snes,&J));
7559566063dSJacob Faibussowitsch     PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix));
7569566063dSJacob Faibussowitsch     PetscCall(MatSetFromOptions(J));
7579566063dSJacob Faibussowitsch     PetscCall(DMCreateMatrix(snes->dm,&B));
75806f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
7599566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,J,B,NULL,NULL));
7609566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
7619566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
762caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
7631ba9b98eSMatthew G. Knepley     PetscDS   prob;
7646cab3a1bSJed Brown     Mat       J, B;
7651ba9b98eSMatthew G. Knepley     PetscBool hasPrec   = PETSC_FALSE;
7661ba9b98eSMatthew G. Knepley 
7676cab3a1bSJed Brown     J    = snes->jacobian;
7689566063dSJacob Faibussowitsch     PetscCall(DMGetDS(dm, &prob));
7699566063dSJacob Faibussowitsch     if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec));
7709566063dSJacob Faibussowitsch     if (J)            PetscCall(PetscObjectReference((PetscObject) J));
7719566063dSJacob Faibussowitsch     else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J));
7729566063dSJacob Faibussowitsch     PetscCall(DMCreateMatrix(snes->dm, &B));
7739566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL));
7749566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&J));
7759566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
7766cab3a1bSJed Brown   }
777caa4e7f2SJed Brown   {
778caa4e7f2SJed Brown     KSP ksp;
7799566063dSJacob Faibussowitsch     PetscCall(SNESGetKSP(snes,&ksp));
7809566063dSJacob Faibussowitsch     PetscCall(KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes));
7819566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes));
782caa4e7f2SJed Brown   }
7836cab3a1bSJed Brown   PetscFunctionReturn(0);
7846cab3a1bSJed Brown }
7856cab3a1bSJed Brown 
7865e7c47f3SMatthew G. Knepley static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes)
7875e7c47f3SMatthew G. Knepley {
7885e7c47f3SMatthew G. Knepley   PetscInt       i;
7895e7c47f3SMatthew G. Knepley 
7905e7c47f3SMatthew G. Knepley   PetscFunctionBegin;
7915e7c47f3SMatthew G. Knepley   if (!snes->pauseFinal) PetscFunctionReturn(0);
7925e7c47f3SMatthew G. Knepley   for (i = 0; i < snes->numbermonitors; ++i) {
7935e7c47f3SMatthew G. Knepley     PetscViewerAndFormat *vf = (PetscViewerAndFormat *) snes->monitorcontext[i];
7945e7c47f3SMatthew G. Knepley     PetscDraw             draw;
7955e7c47f3SMatthew G. Knepley     PetscReal             lpause;
7965e7c47f3SMatthew G. Knepley 
7975e7c47f3SMatthew G. Knepley     if (!vf) continue;
7985e7c47f3SMatthew G. Knepley     if (vf->lg) {
7995e7c47f3SMatthew G. Knepley       if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue;
8005e7c47f3SMatthew G. Knepley       if (((PetscObject) vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue;
8019566063dSJacob Faibussowitsch       PetscCall(PetscDrawLGGetDraw(vf->lg, &draw));
8029566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(draw, &lpause));
8039566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, -1.0));
8049566063dSJacob Faibussowitsch       PetscCall(PetscDrawPause(draw));
8059566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, lpause));
8065e7c47f3SMatthew G. Knepley     } else {
8075e7c47f3SMatthew G. Knepley       PetscBool isdraw;
8085e7c47f3SMatthew G. Knepley 
8095e7c47f3SMatthew G. Knepley       if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue;
8105e7c47f3SMatthew G. Knepley       if (((PetscObject) vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue;
8119566063dSJacob Faibussowitsch       PetscCall(PetscObjectTypeCompare((PetscObject) vf->viewer, PETSCVIEWERDRAW, &isdraw));
8125e7c47f3SMatthew G. Knepley       if (!isdraw) continue;
8139566063dSJacob Faibussowitsch       PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw));
8149566063dSJacob Faibussowitsch       PetscCall(PetscDrawGetPause(draw, &lpause));
8159566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, -1.0));
8169566063dSJacob Faibussowitsch       PetscCall(PetscDrawPause(draw));
8179566063dSJacob Faibussowitsch       PetscCall(PetscDrawSetPause(draw, lpause));
8185e7c47f3SMatthew G. Knepley     }
8195e7c47f3SMatthew G. Knepley   }
8205e7c47f3SMatthew G. Knepley   PetscFunctionReturn(0);
8215e7c47f3SMatthew G. Knepley }
8225e7c47f3SMatthew G. Knepley 
823fde5950dSBarry Smith /*@C
824fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
825fde5950dSBarry Smith 
826fde5950dSBarry Smith    Collective on SNES
827fde5950dSBarry Smith 
828fde5950dSBarry Smith    Input Parameters:
829fde5950dSBarry Smith +  snes - SNES object you wish to monitor
830fde5950dSBarry Smith .  name - the monitor type one is seeking
831fde5950dSBarry Smith .  help - message indicating what monitoring is done
832fde5950dSBarry Smith .  manual - manual page for the monitor
833fde5950dSBarry Smith .  monitor - the monitor function
834fde5950dSBarry 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
835fde5950dSBarry Smith 
836fde5950dSBarry Smith    Level: developer
837fde5950dSBarry Smith 
838db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
839db781477SPatrick Sanan           `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
840db781477SPatrick Sanan           `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`,
841db781477SPatrick Sanan           `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
842c2e3fba1SPatrick Sanan           `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
843db781477SPatrick Sanan           `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
844db781477SPatrick Sanan           `PetscOptionsFList()`, `PetscOptionsEList()`
845fde5950dSBarry Smith @*/
846d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
847fde5950dSBarry Smith {
848fde5950dSBarry Smith   PetscViewer       viewer;
849fde5950dSBarry Smith   PetscViewerFormat format;
850fde5950dSBarry Smith   PetscBool         flg;
851fde5950dSBarry Smith 
852fde5950dSBarry Smith   PetscFunctionBegin;
8539566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg));
854fde5950dSBarry Smith   if (flg) {
855d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
8569566063dSJacob Faibussowitsch     PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf));
8579566063dSJacob Faibussowitsch     PetscCall(PetscObjectDereference((PetscObject)viewer));
858fde5950dSBarry Smith     if (monitorsetup) {
8599566063dSJacob Faibussowitsch       PetscCall((*monitorsetup)(snes,vf));
860fde5950dSBarry Smith     }
8619566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy));
862fde5950dSBarry Smith   }
863fde5950dSBarry Smith   PetscFunctionReturn(0);
864fde5950dSBarry Smith }
865fde5950dSBarry Smith 
8660f0abf79SStefano Zampini PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW* kctx, MPI_Comm comm, const char* prefix)
8670f0abf79SStefano Zampini {
8680f0abf79SStefano Zampini   PetscFunctionBegin;
8690f0abf79SStefano Zampini   PetscOptionsBegin(comm,prefix,"Eisenstat and Walker type forcing options","KSP");
8700f0abf79SStefano Zampini   PetscCall(PetscOptionsInt("-ksp_ew_version","Version 1, 2 or 3",NULL,kctx->version,&kctx->version,NULL));
8710f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_rtol0","0 <= rtol0 < 1",NULL,kctx->rtol_0,&kctx->rtol_0,NULL));
8720f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_rtolmax","0 <= rtolmax < 1",NULL,kctx->rtol_max,&kctx->rtol_max,NULL));
8730f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_gamma","0 <= gamma <= 1",NULL,kctx->gamma,&kctx->gamma,NULL));
8740f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_alpha","1 < alpha <= 2",NULL,kctx->alpha,&kctx->alpha,NULL));
8750f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_alpha2","alpha2",NULL,kctx->alpha2,&kctx->alpha2,NULL));
8760f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_threshold","0 < threshold < 1",NULL,kctx->threshold,&kctx->threshold,NULL));
8770f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p1","p1",NULL,kctx->v4_p1,&kctx->v4_p1,NULL));
8780f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p2","p2",NULL,kctx->v4_p2,&kctx->v4_p2,NULL));
8790f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_p3","p3",NULL,kctx->v4_p3,&kctx->v4_p3,NULL));
8800f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m1","Scaling when rk-1 in [p2,p3)",NULL,kctx->v4_m1,&kctx->v4_m1,NULL));
8810f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m2","Scaling when rk-1 in [p3,+infty)",NULL,kctx->v4_m2,&kctx->v4_m2,NULL));
8820f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m3","Threshold for successive rtol (0.1 in Eq.7)",NULL,kctx->v4_m3,&kctx->v4_m3,NULL));
8830f0abf79SStefano Zampini   PetscCall(PetscOptionsReal("-ksp_ew_v4_m4","Adaptation scaling (0.5 in Eq.7)",NULL,kctx->v4_m4,&kctx->v4_m4,NULL));
8840f0abf79SStefano Zampini   PetscOptionsEnd();
8850f0abf79SStefano Zampini   PetscFunctionReturn(0);
8860f0abf79SStefano Zampini }
8870f0abf79SStefano Zampini 
8889b94acceSBarry Smith /*@
88994b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
8909b94acceSBarry Smith 
891c7afd0dbSLois Curfman McInnes    Collective on SNES
892c7afd0dbSLois Curfman McInnes 
8939b94acceSBarry Smith    Input Parameter:
8949b94acceSBarry Smith .  snes - the SNES context
8959b94acceSBarry Smith 
89636851e7fSLois Curfman McInnes    Options Database Keys:
897722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
89882738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
89982738288SBarry Smith                 of the change in the solution between steps
90070441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
901b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
902e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
903be5caee7SBarry Smith .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
904b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
905b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
9064839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
907ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
908a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
9093d5a8a6aSBarry Smith .  -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve()
910e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
9113d5a8a6aSBarry Smith .  -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve()
912b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
913f362779dSJed Brown .  -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver.
914f362779dSJed Brown                                default SNESConvergedDefault(). skip SNESConvergedSkip() means continue iterating until max_it or some other criterion is reached, saving expense
915f362779dSJed Brown                                of convergence test. correct_pressure SNESConvergedCorrectPressure() has special handling of a pressure null space.
916fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
917fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
918fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
919fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
9204619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
921459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
9225e7c47f3SMatthew G. Knepley .  -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends
923e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
924e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
9255968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
926b5badacbSBarry Smith .  -snes_converged_reason - print the reason for convergence/divergence after each solve
927e62ac41dSBarry Smith .  -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner
928e62ac41dSBarry 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.
929e62ac41dSBarry 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.
93082738288SBarry Smith 
93182738288SBarry Smith     Options Database for Eisenstat-Walker method:
932fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
9334b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
93436851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
93536851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
93636851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
93736851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
93836851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
93936851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
94082738288SBarry Smith 
94111ca99fdSLois Curfman McInnes    Notes:
942ec5066bdSBarry Smith    To see all options, run your program with the -help option or consult the users manual
943ec5066bdSBarry Smith 
944ec5066bdSBarry Smith    Notes:
945a5b23f4aSJose E. Roman       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with
946ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
94783e2fdc7SBarry Smith 
94836851e7fSLois Curfman McInnes    Level: beginner
94936851e7fSLois Curfman McInnes 
950db781477SPatrick Sanan .seealso: `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()`
9519b94acceSBarry Smith @*/
9527087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
9539b94acceSBarry Smith {
9548afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
955d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
95604d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
957649ef022SMatthew Knepley   const char     *convtests[] = {"default","skip","correct_pressure"};
95885385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
9590f0abf79SStefano Zampini   char           type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256];
960c40d0f55SPeter Brune   PCSide         pcside;
961a64e098fSPeter Brune   const char     *optionsprefix;
9629b94acceSBarry Smith 
9633a40ed3dSBarry Smith   PetscFunctionBegin;
9640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9659566063dSJacob Faibussowitsch   PetscCall(SNESRegisterAll());
966d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)snes);
967639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
9689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg));
969d64ed03dSBarry Smith   if (flg) {
9709566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,type));
9717adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
9729566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,deft));
973d64ed03dSBarry Smith   }
9749566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL));
9759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL));
976186905e3SBarry Smith 
9779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL));
9789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL));
9799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL));
9809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL));
9819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL));
9829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL));
9839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL));
9849566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL));
9859566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL));
98685385478SLisandro Dalcin 
9879566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg));
988a8054027SBarry Smith   if (flg) {
9895f80ce2aSJacob 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");
9909566063dSJacob Faibussowitsch     PetscCall(SNESSetLagPreconditioner(snes,lag));
991a8054027SBarry Smith   }
9929566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg));
99337ec4e1aSPeter Brune   if (flg) {
9949566063dSJacob Faibussowitsch     PetscCall(SNESSetLagPreconditionerPersists(snes,persist));
99537ec4e1aSPeter Brune   }
9969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg));
997e35cf81dSBarry Smith   if (flg) {
9985f80ce2aSJacob 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");
9999566063dSJacob Faibussowitsch     PetscCall(SNESSetLagJacobian(snes,lag));
1000e35cf81dSBarry Smith   }
10019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg));
100237ec4e1aSPeter Brune   if (flg) {
10039566063dSJacob Faibussowitsch     PetscCall(SNESSetLagJacobianPersists(snes,persist));
100437ec4e1aSPeter Brune   }
100537ec4e1aSPeter Brune 
10069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg));
1007efd51863SBarry Smith   if (flg) {
10089566063dSJacob Faibussowitsch     PetscCall(SNESSetGridSequence(snes,grids));
1009efd51863SBarry Smith   }
1010a8054027SBarry Smith 
10119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg));
101285385478SLisandro Dalcin   if (flg) {
101385385478SLisandro Dalcin     switch (indx) {
10149566063dSJacob Faibussowitsch     case 0: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL)); break;
10159566063dSJacob Faibussowitsch     case 1: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL)); break;
10169566063dSJacob Faibussowitsch     case 2: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL)); break;
101785385478SLisandro Dalcin     }
101885385478SLisandro Dalcin   }
101985385478SLisandro Dalcin 
10209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg));
10219566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetNormSchedule(snes,(SNESNormSchedule)indx));
1022fdacfa88SPeter Brune 
10239566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg));
10249566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetFunctionType(snes,(SNESFunctionType)indx));
1025186905e3SBarry Smith 
102685385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
102785385478SLisandro Dalcin 
10289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL));
1029186905e3SBarry Smith 
10300f0abf79SStefano Zampini   PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix));
10310f0abf79SStefano Zampini   PetscCall(PetscSNPrintf(ewprefix,sizeof(ewprefix),"%s%s",optionsprefix ? optionsprefix : "","snes_"));
10320f0abf79SStefano Zampini   PetscCall(SNESEWSetFromOptions_Private(kctx,PetscObjectComm((PetscObject)snes),ewprefix));
10330f0abf79SStefano Zampini 
10349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL));
10359566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL));
10369566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL));
10379566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL));
10389566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL));
10399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL));
10409566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL));
1041186905e3SBarry Smith 
104290d69ab7SBarry Smith   flg  = PETSC_FALSE;
10439566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set));
10449566063dSJacob Faibussowitsch   if (set && flg) PetscCall(SNESMonitorCancel(snes));
1045eabae89aSBarry Smith 
10469566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp));
10479566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL));
10489566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL));
1049eabae89aSBarry Smith 
10509566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp));
10519566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL));
10529566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL));
10539566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL));
10549566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL));
10559566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL));
10569566063dSJacob Faibussowitsch   PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL));
10579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL));
10582db13446SMatthew G. Knepley 
10599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg));
10609566063dSJacob Faibussowitsch   if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes,monfilename));
10615180491cSLisandro Dalcin 
106290d69ab7SBarry Smith   flg  = PETSC_FALSE;
10639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL));
1064459f5d12SBarry Smith   if (flg) {
1065459f5d12SBarry Smith     PetscViewer ctx;
1066e24b481bSBarry Smith 
10679566063dSJacob Faibussowitsch     PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx));
10689566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy));
1069459f5d12SBarry Smith   }
10702e7541e6SPeter Brune 
107190d69ab7SBarry Smith   flg  = PETSC_FALSE;
10729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set));
10739566063dSJacob Faibussowitsch   if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes));
1074c4421ceaSFande Kong 
1075c4421ceaSFande Kong   flg  = PETSC_FALSE;
10769566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL));
10774b27c08aSLois Curfman McInnes   if (flg) {
10786cab3a1bSJed Brown     void    *functx;
1079b1f624c7SBarry Smith     DM      dm;
1080b1f624c7SBarry Smith     DMSNES  sdm;
10819566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
10829566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNES(dm,&sdm));
1083b1f624c7SBarry Smith     sdm->jacobianctx = NULL;
10849566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
10859566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx));
10869566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Setting default finite difference Jacobian matrix\n"));
10879b94acceSBarry Smith   }
1088639f9d9dSBarry Smith 
108944848bc4SPeter Brune   flg  = PETSC_FALSE;
10909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL));
109197584545SPeter Brune   if (flg) {
10929566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL));
109397584545SPeter Brune   }
109497584545SPeter Brune 
109597584545SPeter Brune   flg  = PETSC_FALSE;
10969566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL));
109744848bc4SPeter Brune   if (flg) {
1098c52e227fSPeter Brune     DM             dm;
1099c52e227fSPeter Brune     DMSNES         sdm;
11009566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
11019566063dSJacob Faibussowitsch     PetscCall(DMGetDMSNES(dm,&sdm));
1102aace71b7SPeter Brune     sdm->jacobianctx = NULL;
11039566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL));
11049566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n"));
110544848bc4SPeter Brune   }
110644848bc4SPeter Brune 
1107aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
11089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg));
1109d8f46077SPeter Brune   if (flg && snes->mf_operator) {
1110a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
1111d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
1112a8248277SBarry Smith   }
1113aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
11149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg));
1115d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
11169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL));
1117d28543b3SPeter Brune 
1118c40d0f55SPeter Brune   flg  = PETSC_FALSE;
11199566063dSJacob Faibussowitsch   PetscCall(SNESGetNPCSide(snes,&pcside));
11209566063dSJacob Faibussowitsch   PetscCall(PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg));
11219566063dSJacob Faibussowitsch   if (flg) PetscCall(SNESSetNPCSide(snes,pcside));
1122c40d0f55SPeter Brune 
1123e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
11248a70d858SHong Zhang   /*
11258a70d858SHong Zhang     Publish convergence information using SAWs
11268a70d858SHong Zhang   */
11278a70d858SHong Zhang   flg  = PETSC_FALSE;
11289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL));
11298a70d858SHong Zhang   if (flg) {
11308a70d858SHong Zhang     void *ctx;
11319566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSAWsCreate(snes,&ctx));
11329566063dSJacob Faibussowitsch     PetscCall(SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy));
11338a70d858SHong Zhang   }
11348a70d858SHong Zhang #endif
11358a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
1136b90c6cbeSBarry Smith   {
1137b90c6cbeSBarry Smith   PetscBool set;
1138b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
11399566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set));
1140b90c6cbeSBarry Smith   if (set) {
11419566063dSJacob Faibussowitsch     PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes,flg));
1142b90c6cbeSBarry Smith   }
1143b90c6cbeSBarry Smith   }
1144b90c6cbeSBarry Smith #endif
1145b90c6cbeSBarry Smith 
114676b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
11479566063dSJacob Faibussowitsch     PetscCall((*othersetfromoptions[i])(snes));
114876b2cf59SMatthew Knepley   }
114976b2cf59SMatthew Knepley 
1150e7788613SBarry Smith   if (snes->ops->setfromoptions) {
11519566063dSJacob Faibussowitsch     PetscCall((*snes->ops->setfromoptions)(PetscOptionsObject,snes));
1152639f9d9dSBarry Smith   }
11535d973c19SBarry Smith 
11545d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
11559566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes));
1156d0609cedSBarry Smith   PetscOptionsEnd();
11574bbc92c1SBarry Smith 
1158d8d34be6SBarry Smith   if (snes->linesearch) {
11599566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
11609566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetFromOptions(snes->linesearch));
1161d8d34be6SBarry Smith   }
11629e764e56SPeter Brune 
11636aa5e7e9SBarry Smith   if (snes->usesksp) {
11649566063dSJacob Faibussowitsch     if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
11659566063dSJacob Faibussowitsch     PetscCall(KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre));
11669566063dSJacob Faibussowitsch     PetscCall(KSPSetFromOptions(snes->ksp));
11676aa5e7e9SBarry Smith   }
11686991f827SBarry Smith 
1169b5badacbSBarry Smith   /* if user has set the SNES NPC type via options database, create it. */
11709566063dSJacob Faibussowitsch   PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
11719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset));
1172efd4aadfSBarry Smith   if (pcset && (!snes->npc)) {
11739566063dSJacob Faibussowitsch     PetscCall(SNESGetNPC(snes, &snes->npc));
117451e86f29SPeter Brune   }
1175b5badacbSBarry Smith   if (snes->npc) {
11769566063dSJacob Faibussowitsch     PetscCall(SNESSetFromOptions(snes->npc));
1177b5badacbSBarry Smith   }
1178b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled++;
1179b3cd9a81SMatthew G. Knepley   PetscFunctionReturn(0);
1180b3cd9a81SMatthew G. Knepley }
1181b3cd9a81SMatthew G. Knepley 
1182b3cd9a81SMatthew G. Knepley /*@
1183b3cd9a81SMatthew G. Knepley    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options
1184b3cd9a81SMatthew G. Knepley 
1185b3cd9a81SMatthew G. Knepley    Collective on SNES
1186b3cd9a81SMatthew G. Knepley 
1187b3cd9a81SMatthew G. Knepley    Input Parameter:
1188b3cd9a81SMatthew G. Knepley .  snes - the SNES context
1189b3cd9a81SMatthew G. Knepley 
1190b3cd9a81SMatthew G. Knepley    Level: beginner
1191b3cd9a81SMatthew G. Knepley 
1192db781477SPatrick Sanan .seealso: `SNESSetFromOptions()`, `SNESSetOptionsPrefix()`
1193b3cd9a81SMatthew G. Knepley @*/
1194b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes)
1195b3cd9a81SMatthew G. Knepley {
1196b3cd9a81SMatthew G. Knepley   PetscFunctionBegin;
11979566063dSJacob Faibussowitsch   if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes));
11983a40ed3dSBarry Smith   PetscFunctionReturn(0);
11999b94acceSBarry Smith }
12009b94acceSBarry Smith 
1201bb9467b5SJed Brown /*@C
1202d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1203d25893d9SBarry Smith    the nonlinear solvers.
1204d25893d9SBarry Smith 
1205d25893d9SBarry Smith    Logically Collective on SNES
1206d25893d9SBarry Smith 
1207d25893d9SBarry Smith    Input Parameters:
1208d25893d9SBarry Smith +  snes - the SNES context
1209d25893d9SBarry Smith .  compute - function to compute the context
1210d25893d9SBarry Smith -  destroy - function to destroy the context
1211d25893d9SBarry Smith 
1212d25893d9SBarry Smith    Level: intermediate
1213d25893d9SBarry Smith 
1214bb9467b5SJed Brown    Notes:
1215bb9467b5SJed Brown    This function is currently not available from Fortran.
1216bb9467b5SJed Brown 
1217db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()`
1218d25893d9SBarry Smith @*/
1219d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
1220d25893d9SBarry Smith {
1221d25893d9SBarry Smith   PetscFunctionBegin;
1222d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1223d25893d9SBarry Smith   snes->ops->usercompute = compute;
1224d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
1225d25893d9SBarry Smith   PetscFunctionReturn(0);
1226d25893d9SBarry Smith }
1227a847f771SSatish Balay 
1228b07ff414SBarry Smith /*@
12299b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
12309b94acceSBarry Smith    the nonlinear solvers.
12319b94acceSBarry Smith 
12323f9fe445SBarry Smith    Logically Collective on SNES
1233fee21e36SBarry Smith 
1234c7afd0dbSLois Curfman McInnes    Input Parameters:
1235c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1236c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1237c7afd0dbSLois Curfman McInnes 
123836851e7fSLois Curfman McInnes    Level: intermediate
123936851e7fSLois Curfman McInnes 
124095452b02SPatrick Sanan    Fortran Notes:
124195452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1242daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1243daf670e6SBarry Smith 
1244db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()`
12459b94acceSBarry Smith @*/
12467087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
12479b94acceSBarry Smith {
1248b07ff414SBarry Smith   KSP            ksp;
12491b2093e4SBarry Smith 
12503a40ed3dSBarry Smith   PetscFunctionBegin;
12510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12529566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,&ksp));
12539566063dSJacob Faibussowitsch   PetscCall(KSPSetApplicationContext(ksp,usrP));
12549b94acceSBarry Smith   snes->user = usrP;
12553a40ed3dSBarry Smith   PetscFunctionReturn(0);
12569b94acceSBarry Smith }
125774679c65SBarry Smith 
1258b07ff414SBarry Smith /*@
12599b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
12609b94acceSBarry Smith    nonlinear solvers.
12619b94acceSBarry Smith 
1262c7afd0dbSLois Curfman McInnes    Not Collective
1263c7afd0dbSLois Curfman McInnes 
12649b94acceSBarry Smith    Input Parameter:
12659b94acceSBarry Smith .  snes - SNES context
12669b94acceSBarry Smith 
12679b94acceSBarry Smith    Output Parameter:
12689b94acceSBarry Smith .  usrP - user context
12699b94acceSBarry Smith 
127095452b02SPatrick Sanan    Fortran Notes:
127195452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1272daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1273daf670e6SBarry Smith 
127436851e7fSLois Curfman McInnes    Level: intermediate
127536851e7fSLois Curfman McInnes 
1276db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()`
12779b94acceSBarry Smith @*/
1278e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
12799b94acceSBarry Smith {
12803a40ed3dSBarry Smith   PetscFunctionBegin;
12810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1282e71120c6SJed Brown   *(void**)usrP = snes->user;
12833a40ed3dSBarry Smith   PetscFunctionReturn(0);
12849b94acceSBarry Smith }
128574679c65SBarry Smith 
12869b94acceSBarry Smith /*@
1287ec5066bdSBarry Smith    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian.
12883565c898SBarry Smith 
12893565c898SBarry Smith    Collective on SNES
12903565c898SBarry Smith 
12913565c898SBarry Smith    Input Parameters:
12923565c898SBarry Smith +  snes - SNES context
12934ddffce6SLisandro Dalcin .  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
12944ddffce6SLisandro Dalcin -  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
12953565c898SBarry Smith 
12963565c898SBarry Smith    Options Database:
12973565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
1298ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator
1299ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences.
1300ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow)
13013565c898SBarry Smith 
13023565c898SBarry Smith    Level: intermediate
13033565c898SBarry Smith 
1304ec5066bdSBarry Smith    Notes:
1305a5b23f4aSJose E. Roman       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with
1306ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
1307ec5066bdSBarry Smith 
1308db781477SPatrick Sanan .seealso: `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()`
13093565c898SBarry Smith @*/
13103565c898SBarry Smith PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
13113565c898SBarry Smith {
13123565c898SBarry Smith   PetscFunctionBegin;
13133565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
131488b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf_operator,2);
131588b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf,3);
13164ddffce6SLisandro Dalcin   snes->mf          = mf_operator ? PETSC_TRUE : mf;
13173565c898SBarry Smith   snes->mf_operator = mf_operator;
13183565c898SBarry Smith   PetscFunctionReturn(0);
13193565c898SBarry Smith }
13203565c898SBarry Smith 
13213565c898SBarry Smith /*@
1322ec5066bdSBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian.
13233565c898SBarry Smith 
13243565c898SBarry Smith    Collective on SNES
13253565c898SBarry Smith 
13263565c898SBarry Smith    Input Parameter:
13273565c898SBarry Smith .  snes - SNES context
13283565c898SBarry Smith 
13293565c898SBarry Smith    Output Parameters:
13304ddffce6SLisandro Dalcin +  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
13314ddffce6SLisandro Dalcin -  mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored
13323565c898SBarry Smith 
13333565c898SBarry Smith    Options Database:
13343565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
13353565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
13363565c898SBarry Smith 
13373565c898SBarry Smith    Level: intermediate
13383565c898SBarry Smith 
1339db781477SPatrick Sanan .seealso: `SNESSetUseMatrixFree()`, `MatCreateSNESMF()`
13403565c898SBarry Smith @*/
13413565c898SBarry Smith PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
13423565c898SBarry Smith {
13433565c898SBarry Smith   PetscFunctionBegin;
13443565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13453565c898SBarry Smith   if (mf)          *mf          = snes->mf;
13463565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
13473565c898SBarry Smith   PetscFunctionReturn(0);
13483565c898SBarry Smith }
13493565c898SBarry Smith 
13503565c898SBarry Smith /*@
1351c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1352c8228a4eSBarry Smith    at this time.
13539b94acceSBarry Smith 
1354c7afd0dbSLois Curfman McInnes    Not Collective
1355c7afd0dbSLois Curfman McInnes 
13569b94acceSBarry Smith    Input Parameter:
13579b94acceSBarry Smith .  snes - SNES context
13589b94acceSBarry Smith 
13599b94acceSBarry Smith    Output Parameter:
13609b94acceSBarry Smith .  iter - iteration number
13619b94acceSBarry Smith 
1362c8228a4eSBarry Smith    Notes:
1363c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1364c8228a4eSBarry Smith 
1365c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
136608405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
136708405cd6SLois Curfman McInnes .vb
136808405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
136908405cd6SLois Curfman McInnes       if (!(it % 2)) {
137008405cd6SLois Curfman McInnes         [compute Jacobian here]
137108405cd6SLois Curfman McInnes       }
137208405cd6SLois Curfman McInnes .ve
1373c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
137408405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1375c8228a4eSBarry Smith 
1376c04deec6SBarry Smith    After the SNES solve is complete this will return the number of nonlinear iterations used.
1377c04deec6SBarry Smith 
137836851e7fSLois Curfman McInnes    Level: intermediate
137936851e7fSLois Curfman McInnes 
1380db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()`
13819b94acceSBarry Smith @*/
13827087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
13839b94acceSBarry Smith {
13843a40ed3dSBarry Smith   PetscFunctionBegin;
13850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13864482741eSBarry Smith   PetscValidIntPointer(iter,2);
13879b94acceSBarry Smith   *iter = snes->iter;
13883a40ed3dSBarry Smith   PetscFunctionReturn(0);
13899b94acceSBarry Smith }
139074679c65SBarry Smith 
1391360c497dSPeter Brune /*@
1392360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1393360c497dSPeter Brune 
1394360c497dSPeter Brune    Not Collective
1395360c497dSPeter Brune 
1396d8d19677SJose E. Roman    Input Parameters:
1397a2b725a8SWilliam Gropp +  snes - SNES context
1398a2b725a8SWilliam Gropp -  iter - iteration number
1399360c497dSPeter Brune 
1400360c497dSPeter Brune    Level: developer
1401360c497dSPeter Brune 
1402db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()`
1403360c497dSPeter Brune @*/
1404360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1405360c497dSPeter Brune {
1406360c497dSPeter Brune   PetscFunctionBegin;
1407360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14089566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes));
1409360c497dSPeter Brune   snes->iter = iter;
14109566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes));
1411360c497dSPeter Brune   PetscFunctionReturn(0);
1412360c497dSPeter Brune }
1413360c497dSPeter Brune 
14149b94acceSBarry Smith /*@
1415b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
14169b94acceSBarry Smith    attempted by the nonlinear solver.
14179b94acceSBarry Smith 
1418c7afd0dbSLois Curfman McInnes    Not Collective
1419c7afd0dbSLois Curfman McInnes 
14209b94acceSBarry Smith    Input Parameter:
14219b94acceSBarry Smith .  snes - SNES context
14229b94acceSBarry Smith 
14239b94acceSBarry Smith    Output Parameter:
14249b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
14259b94acceSBarry Smith 
1426c96a6f78SLois Curfman McInnes    Notes:
1427c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1428c96a6f78SLois Curfman McInnes 
142936851e7fSLois Curfman McInnes    Level: intermediate
143036851e7fSLois Curfman McInnes 
1431db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1432db781477SPatrick Sanan           `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()`
14339b94acceSBarry Smith @*/
14347087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
14359b94acceSBarry Smith {
14363a40ed3dSBarry Smith   PetscFunctionBegin;
14370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14384482741eSBarry Smith   PetscValidIntPointer(nfails,2);
143950ffb88aSMatthew Knepley   *nfails = snes->numFailures;
144050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
144150ffb88aSMatthew Knepley }
144250ffb88aSMatthew Knepley 
144350ffb88aSMatthew Knepley /*@
1444b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
144550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
144650ffb88aSMatthew Knepley 
144750ffb88aSMatthew Knepley    Not Collective
144850ffb88aSMatthew Knepley 
144950ffb88aSMatthew Knepley    Input Parameters:
145050ffb88aSMatthew Knepley +  snes     - SNES context
145150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
145250ffb88aSMatthew Knepley 
145350ffb88aSMatthew Knepley    Level: intermediate
145450ffb88aSMatthew Knepley 
1455db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1456db781477SPatrick Sanan           `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
145750ffb88aSMatthew Knepley @*/
14587087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
145950ffb88aSMatthew Knepley {
146050ffb88aSMatthew Knepley   PetscFunctionBegin;
14610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
146250ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
146350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
146450ffb88aSMatthew Knepley }
146550ffb88aSMatthew Knepley 
146650ffb88aSMatthew Knepley /*@
1467b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
146850ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
146950ffb88aSMatthew Knepley 
147050ffb88aSMatthew Knepley    Not Collective
147150ffb88aSMatthew Knepley 
147250ffb88aSMatthew Knepley    Input Parameter:
147350ffb88aSMatthew Knepley .  snes     - SNES context
147450ffb88aSMatthew Knepley 
147550ffb88aSMatthew Knepley    Output Parameter:
147650ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
147750ffb88aSMatthew Knepley 
147850ffb88aSMatthew Knepley    Level: intermediate
147950ffb88aSMatthew Knepley 
1480db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`,
1481db781477SPatrick Sanan           `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()`
148258ebbce7SBarry Smith 
148350ffb88aSMatthew Knepley @*/
14847087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
148550ffb88aSMatthew Knepley {
148650ffb88aSMatthew Knepley   PetscFunctionBegin;
14870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14884482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
148950ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
14903a40ed3dSBarry Smith   PetscFunctionReturn(0);
14919b94acceSBarry Smith }
1492a847f771SSatish Balay 
14932541af92SBarry Smith /*@
14942541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
14952541af92SBarry Smith      done by SNES.
14962541af92SBarry Smith 
14972541af92SBarry Smith    Not Collective
14982541af92SBarry Smith 
14992541af92SBarry Smith    Input Parameter:
15002541af92SBarry Smith .  snes     - SNES context
15012541af92SBarry Smith 
15022541af92SBarry Smith    Output Parameter:
15032541af92SBarry Smith .  nfuncs - number of evaluations
15042541af92SBarry Smith 
15052541af92SBarry Smith    Level: intermediate
15062541af92SBarry Smith 
150795452b02SPatrick Sanan    Notes:
150895452b02SPatrick Sanan     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1509971e163fSPeter Brune 
1510db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()`
15112541af92SBarry Smith @*/
15127087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
15132541af92SBarry Smith {
15142541af92SBarry Smith   PetscFunctionBegin;
15150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15162541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
15172541af92SBarry Smith   *nfuncs = snes->nfuncs;
15182541af92SBarry Smith   PetscFunctionReturn(0);
15192541af92SBarry Smith }
15202541af92SBarry Smith 
15213d4c4710SBarry Smith /*@
15223d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
15233d4c4710SBarry Smith    linear solvers.
15243d4c4710SBarry Smith 
15253d4c4710SBarry Smith    Not Collective
15263d4c4710SBarry Smith 
15273d4c4710SBarry Smith    Input Parameter:
15283d4c4710SBarry Smith .  snes - SNES context
15293d4c4710SBarry Smith 
15303d4c4710SBarry Smith    Output Parameter:
15313d4c4710SBarry Smith .  nfails - number of failed solves
15323d4c4710SBarry Smith 
15339d85da0cSMatthew G. Knepley    Level: intermediate
15349d85da0cSMatthew G. Knepley 
15359d85da0cSMatthew G. Knepley    Options Database Keys:
15369d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15379d85da0cSMatthew G. Knepley 
15383d4c4710SBarry Smith    Notes:
15393d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
15403d4c4710SBarry Smith 
1541db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`
15423d4c4710SBarry Smith @*/
15437087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
15443d4c4710SBarry Smith {
15453d4c4710SBarry Smith   PetscFunctionBegin;
15460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15473d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
15483d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
15493d4c4710SBarry Smith   PetscFunctionReturn(0);
15503d4c4710SBarry Smith }
15513d4c4710SBarry Smith 
15523d4c4710SBarry Smith /*@
15533d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
15543d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
15553d4c4710SBarry Smith 
15563f9fe445SBarry Smith    Logically Collective on SNES
15573d4c4710SBarry Smith 
15583d4c4710SBarry Smith    Input Parameters:
15593d4c4710SBarry Smith +  snes     - SNES context
15603d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
15613d4c4710SBarry Smith 
15623d4c4710SBarry Smith    Level: intermediate
15633d4c4710SBarry Smith 
15649d85da0cSMatthew G. Knepley    Options Database Keys:
15659d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15669d85da0cSMatthew G. Knepley 
156795452b02SPatrick Sanan    Notes:
156895452b02SPatrick Sanan     By default this is 0; that is SNES returns on the first failed linear solve
15693d4c4710SBarry Smith 
1570db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`
15713d4c4710SBarry Smith @*/
15727087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
15733d4c4710SBarry Smith {
15743d4c4710SBarry Smith   PetscFunctionBegin;
15750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1576c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
15773d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
15783d4c4710SBarry Smith   PetscFunctionReturn(0);
15793d4c4710SBarry Smith }
15803d4c4710SBarry Smith 
15813d4c4710SBarry Smith /*@
15823d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
15833d4c4710SBarry Smith      are allowed before SNES terminates
15843d4c4710SBarry Smith 
15853d4c4710SBarry Smith    Not Collective
15863d4c4710SBarry Smith 
15873d4c4710SBarry Smith    Input Parameter:
15883d4c4710SBarry Smith .  snes     - SNES context
15893d4c4710SBarry Smith 
15903d4c4710SBarry Smith    Output Parameter:
15913d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
15923d4c4710SBarry Smith 
15933d4c4710SBarry Smith    Level: intermediate
15943d4c4710SBarry Smith 
159595452b02SPatrick Sanan    Notes:
159695452b02SPatrick Sanan     By default this is 1; that is SNES returns on the first failed linear solve
15973d4c4710SBarry Smith 
1598db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`,
15993d4c4710SBarry Smith @*/
16007087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
16013d4c4710SBarry Smith {
16023d4c4710SBarry Smith   PetscFunctionBegin;
16030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16043d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
16053d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
16063d4c4710SBarry Smith   PetscFunctionReturn(0);
16073d4c4710SBarry Smith }
16083d4c4710SBarry Smith 
1609c96a6f78SLois Curfman McInnes /*@
1610b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1611c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1612c96a6f78SLois Curfman McInnes 
1613c7afd0dbSLois Curfman McInnes    Not Collective
1614c7afd0dbSLois Curfman McInnes 
1615c96a6f78SLois Curfman McInnes    Input Parameter:
1616c96a6f78SLois Curfman McInnes .  snes - SNES context
1617c96a6f78SLois Curfman McInnes 
1618c96a6f78SLois Curfman McInnes    Output Parameter:
1619c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1620c96a6f78SLois Curfman McInnes 
1621c96a6f78SLois Curfman McInnes    Notes:
1622971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1623c96a6f78SLois Curfman McInnes 
1624010be392SBarry 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
1625010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1626010be392SBarry Smith 
162736851e7fSLois Curfman McInnes    Level: intermediate
162836851e7fSLois Curfman McInnes 
1629db781477SPatrick Sanan .seealso: `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()`
1630c96a6f78SLois Curfman McInnes @*/
16317087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1632c96a6f78SLois Curfman McInnes {
16333a40ed3dSBarry Smith   PetscFunctionBegin;
16340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16354482741eSBarry Smith   PetscValidIntPointer(lits,2);
1636c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
16373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1638c96a6f78SLois Curfman McInnes }
1639c96a6f78SLois Curfman McInnes 
1640971e163fSPeter Brune /*@
1641971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1642971e163fSPeter Brune    are reset every time SNESSolve() is called.
1643971e163fSPeter Brune 
1644971e163fSPeter Brune    Logically Collective on SNES
1645971e163fSPeter Brune 
1646d8d19677SJose E. Roman    Input Parameters:
1647971e163fSPeter Brune +  snes - SNES context
1648971e163fSPeter Brune -  reset - whether to reset the counters or not
1649971e163fSPeter Brune 
1650971e163fSPeter Brune    Notes:
1651fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1652971e163fSPeter Brune 
1653971e163fSPeter Brune    Level: developer
1654971e163fSPeter Brune 
1655db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()`
1656971e163fSPeter Brune @*/
1657971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1658971e163fSPeter Brune {
1659971e163fSPeter Brune   PetscFunctionBegin;
1660971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1661971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1662971e163fSPeter Brune   snes->counters_reset = reset;
1663971e163fSPeter Brune   PetscFunctionReturn(0);
1664971e163fSPeter Brune }
1665971e163fSPeter Brune 
16662999313aSBarry Smith /*@
16672999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
16682999313aSBarry Smith 
16692999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
16702999313aSBarry Smith 
16712999313aSBarry Smith    Input Parameters:
16722999313aSBarry Smith +  snes - the SNES context
16732999313aSBarry Smith -  ksp - the KSP context
16742999313aSBarry Smith 
16752999313aSBarry Smith    Notes:
16762999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
16772999313aSBarry Smith    so this routine is rarely needed.
16782999313aSBarry Smith 
16792999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
16802999313aSBarry Smith    decreased by one.
16812999313aSBarry Smith 
16822999313aSBarry Smith    Level: developer
16832999313aSBarry Smith 
1684db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
16852999313aSBarry Smith @*/
16867087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
16872999313aSBarry Smith {
16882999313aSBarry Smith   PetscFunctionBegin;
16890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16900700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
16912999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
16929566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)ksp));
16939566063dSJacob Faibussowitsch   if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp));
16942999313aSBarry Smith   snes->ksp = ksp;
16952999313aSBarry Smith   PetscFunctionReturn(0);
16962999313aSBarry Smith }
16972999313aSBarry Smith 
16989b94acceSBarry Smith /* -----------------------------------------------------------*/
169952baeb72SSatish Balay /*@
17009b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
17019b94acceSBarry Smith 
1702d083f849SBarry Smith    Collective
1703c7afd0dbSLois Curfman McInnes 
1704c7afd0dbSLois Curfman McInnes    Input Parameters:
1705906ed7ccSBarry Smith .  comm - MPI communicator
17069b94acceSBarry Smith 
17079b94acceSBarry Smith    Output Parameter:
17089b94acceSBarry Smith .  outsnes - the new SNES context
17099b94acceSBarry Smith 
1710c7afd0dbSLois Curfman McInnes    Options Database Keys:
1711c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1712c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1713c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1714c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1715c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1716c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1717c1f60f51SBarry Smith 
171836851e7fSLois Curfman McInnes    Level: beginner
171936851e7fSLois Curfman McInnes 
172095452b02SPatrick Sanan    Developer Notes:
172195452b02SPatrick Sanan     SNES always creates a KSP object even though many SNES methods do not use it. This is
1722efd4aadfSBarry Smith                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1723efd4aadfSBarry Smith                     particular method does use KSP and regulates if the information about the KSP is printed
1724efd4aadfSBarry Smith                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1725efd4aadfSBarry Smith                     by help messages about meaningless SNES options.
1726efd4aadfSBarry Smith 
1727efd4aadfSBarry Smith                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1728efd4aadfSBarry Smith                     be fixed.
1729efd4aadfSBarry Smith 
1730db781477SPatrick Sanan .seealso: `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
1731a8054027SBarry Smith 
17329b94acceSBarry Smith @*/
17337087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
17349b94acceSBarry Smith {
17359b94acceSBarry Smith   SNES      snes;
1736fa9f3622SBarry Smith   SNESKSPEW *kctx;
173737fcc0dbSBarry Smith 
17383a40ed3dSBarry Smith   PetscFunctionBegin;
1739ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
17400298fd71SBarry Smith   *outsnes = NULL;
17419566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
17428ba1e511SMatthew Knepley 
17439566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView));
17447adad957SLisandro Dalcin 
17458d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
17462c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
174788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
17489b94acceSBarry Smith   snes->max_its           = 50;
17499750a799SBarry Smith   snes->max_funcs         = 10000;
17509b94acceSBarry Smith   snes->norm              = 0.0;
1751c1e67a49SFande Kong   snes->xnorm             = 0.0;
1752c1e67a49SFande Kong   snes->ynorm             = 0.0;
1753365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
17546c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
17553a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17563a2046daSBarry Smith   snes->rtol              = 1.e-5;
17573a2046daSBarry Smith #else
1758b4874afaSBarry Smith   snes->rtol              = 1.e-8;
17593a2046daSBarry Smith #endif
1760b4874afaSBarry Smith   snes->ttol              = 0.0;
17613a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17623a2046daSBarry Smith   snes->abstol            = 1.e-25;
17633a2046daSBarry Smith #else
176470441072SBarry Smith   snes->abstol            = 1.e-50;
17653a2046daSBarry Smith #endif
17667cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
17677cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
17687cd0ae37SLisandro Dalcin #else
1769c60f73f4SPeter Brune   snes->stol              = 1.e-8;
17707cd0ae37SLisandro Dalcin #endif
17713a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17723a2046daSBarry Smith   snes->deltatol          = 1.e-6;
17733a2046daSBarry Smith #else
17744b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
17753a2046daSBarry Smith #endif
1776e37c518bSBarry Smith   snes->divtol            = 1.e4;
1777e37c518bSBarry Smith   snes->rnorm0            = 0;
17789b94acceSBarry Smith   snes->nfuncs            = 0;
177950ffb88aSMatthew Knepley   snes->numFailures       = 0;
178050ffb88aSMatthew Knepley   snes->maxFailures       = 1;
17817a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1782e35cf81dSBarry Smith   snes->lagjacobian       = 1;
178337ec4e1aSPeter Brune   snes->jac_iter          = 0;
178437ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1785a8054027SBarry Smith   snes->lagpreconditioner = 1;
178637ec4e1aSPeter Brune   snes->pre_iter          = 0;
178737ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1788639f9d9dSBarry Smith   snes->numbermonitors    = 0;
1789c4421ceaSFande Kong   snes->numberreasonviews = 0;
17909e5d0892SLisandro Dalcin   snes->data              = NULL;
17914dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1792186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
17936f24a144SLois Curfman McInnes   snes->nwork             = 0;
17949e5d0892SLisandro Dalcin   snes->work              = NULL;
179558c9b817SLisandro Dalcin   snes->nvwork            = 0;
17969e5d0892SLisandro Dalcin   snes->vwork             = NULL;
1797758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1798758f92a0SBarry Smith   snes->conv_hist_max     = 0;
17990298fd71SBarry Smith   snes->conv_hist         = NULL;
18000298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1801758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1802971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1803e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1804184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1805efd4aadfSBarry Smith   snes->npcside           = PC_RIGHT;
1806b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled = 0;
1807c40d0f55SPeter Brune 
1808d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1809d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1810d8f46077SPeter Brune   snes->mf_version  = 1;
1811d8f46077SPeter Brune 
18123d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
18133d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
18143d4c4710SBarry Smith 
1815349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
181676bd3646SJed Brown   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1817349187a7SBarry Smith 
18184fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
18194fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
18204fc747eaSLawrence Mitchell 
18219b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
18229566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(snes,&kctx));
1823f5af7f23SKarl Rupp 
18249b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
18259b94acceSBarry Smith   kctx->version     = 2;
18260f0abf79SStefano Zampini   kctx->rtol_0      = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but
18279b94acceSBarry Smith                              this was too large for some test cases */
182875567043SBarry Smith   kctx->rtol_last   = 0.0;
18290f0abf79SStefano Zampini   kctx->rtol_max    = 0.9;
18309b94acceSBarry Smith   kctx->gamma       = 1.0;
18310f0abf79SStefano Zampini   kctx->alpha       = 0.5*(1.0 + PetscSqrtReal(5.0));
183271f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
18330f0abf79SStefano Zampini   kctx->threshold   = 0.1;
183475567043SBarry Smith   kctx->lresid_last = 0.0;
183575567043SBarry Smith   kctx->norm_last   = 0.0;
18369b94acceSBarry Smith 
18370f0abf79SStefano Zampini   kctx->rk_last     = 0.0;
18380f0abf79SStefano Zampini   kctx->rk_last_2   = 0.0;
18390f0abf79SStefano Zampini   kctx->rtol_last_2 = 0.0;
18400f0abf79SStefano Zampini   kctx->v4_p1       = 0.1;
18410f0abf79SStefano Zampini   kctx->v4_p2       = 0.4;
18420f0abf79SStefano Zampini   kctx->v4_p3       = 0.7;
18430f0abf79SStefano Zampini   kctx->v4_m1       = 0.8;
18440f0abf79SStefano Zampini   kctx->v4_m2       = 0.5;
18450f0abf79SStefano Zampini   kctx->v4_m3       = 0.1;
18460f0abf79SStefano Zampini   kctx->v4_m4       = 0.5;
18470f0abf79SStefano Zampini 
18489b94acceSBarry Smith   *outsnes = snes;
18493a40ed3dSBarry Smith   PetscFunctionReturn(0);
18509b94acceSBarry Smith }
18519b94acceSBarry Smith 
185288f0584fSBarry Smith /*MC
1853411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
185488f0584fSBarry Smith 
185588f0584fSBarry Smith      Synopsis:
1856411c0326SBarry Smith      #include "petscsnes.h"
1857411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
185888f0584fSBarry Smith 
18591843f636SBarry Smith      Collective on snes
18601843f636SBarry Smith 
186188f0584fSBarry Smith      Input Parameters:
186288f0584fSBarry Smith +     snes - the SNES context
186388f0584fSBarry Smith .     x    - state at which to evaluate residual
186488f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
186588f0584fSBarry Smith 
186688f0584fSBarry Smith      Output Parameter:
186788f0584fSBarry Smith .     f  - vector to put residual (function value)
186888f0584fSBarry Smith 
1869878cb397SSatish Balay    Level: intermediate
1870878cb397SSatish Balay 
1871db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`
187288f0584fSBarry Smith M*/
187388f0584fSBarry Smith 
18749b94acceSBarry Smith /*@C
18759b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
18769b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
18779b94acceSBarry Smith    equations.
18789b94acceSBarry Smith 
18793f9fe445SBarry Smith    Logically Collective on SNES
1880fee21e36SBarry Smith 
1881c7afd0dbSLois Curfman McInnes    Input Parameters:
1882c7afd0dbSLois Curfman McInnes +  snes - the SNES context
18836b7fb656SBarry Smith .  r - vector to store function values, may be NULL
1884f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1885c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
18860298fd71SBarry Smith          function evaluation routine (may be NULL)
18879b94acceSBarry Smith 
18889b94acceSBarry Smith    Notes:
18899b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
18909b94acceSBarry Smith $      f'(x) x = -f(x),
1891c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
18929b94acceSBarry Smith 
189336851e7fSLois Curfman McInnes    Level: beginner
189436851e7fSLois Curfman McInnes 
1895db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction`
18969b94acceSBarry Smith @*/
1897f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
18989b94acceSBarry Smith {
18996cab3a1bSJed Brown   DM             dm;
19006cab3a1bSJed Brown 
19013a40ed3dSBarry Smith   PetscFunctionBegin;
19020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1903d2a683ecSLisandro Dalcin   if (r) {
1904d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1905d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
19069566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)r));
19079566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_func));
190885385478SLisandro Dalcin     snes->vec_func = r;
1909d2a683ecSLisandro Dalcin   }
19109566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
19119566063dSJacob Faibussowitsch   PetscCall(DMSNESSetFunction(dm,f,ctx));
1912bbc1464cSBarry Smith   if (f == SNESPicardComputeFunction) {
19139566063dSJacob Faibussowitsch     PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx));
1914bbc1464cSBarry Smith   }
19153a40ed3dSBarry Smith   PetscFunctionReturn(0);
19169b94acceSBarry Smith }
19179b94acceSBarry Smith 
1918e4ed7901SPeter Brune /*@C
1919e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1920e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1921e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1922e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1923e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1924e4ed7901SPeter Brune 
1925e4ed7901SPeter Brune    Logically Collective on SNES
1926e4ed7901SPeter Brune 
1927e4ed7901SPeter Brune    Input Parameters:
1928e4ed7901SPeter Brune +  snes - the SNES context
1929e4ed7901SPeter Brune -  f - vector to store function value
1930e4ed7901SPeter Brune 
1931e4ed7901SPeter Brune    Notes:
1932e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1933e4ed7901SPeter Brune 
1934e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1935e4ed7901SPeter Brune 
1936e4ed7901SPeter Brune    Level: developer
1937e4ed7901SPeter Brune 
1938db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()`
1939e4ed7901SPeter Brune @*/
1940e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1941e4ed7901SPeter Brune {
1942e4ed7901SPeter Brune   Vec            vec_func;
1943e4ed7901SPeter Brune 
1944e4ed7901SPeter Brune   PetscFunctionBegin;
1945e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1946e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1947e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1948efd4aadfSBarry Smith   if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1949902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1950902f982fSPeter Brune     PetscFunctionReturn(0);
1951902f982fSPeter Brune   }
19529566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,&vec_func,NULL,NULL));
19539566063dSJacob Faibussowitsch   PetscCall(VecCopy(f,vec_func));
1954f5af7f23SKarl Rupp 
1955217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1956e4ed7901SPeter Brune   PetscFunctionReturn(0);
1957e4ed7901SPeter Brune }
1958e4ed7901SPeter Brune 
1959534ebe21SPeter Brune /*@
1960a5b23f4aSJose E. Roman    SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring
1961534ebe21SPeter Brune    of the SNES method.
1962534ebe21SPeter Brune 
1963534ebe21SPeter Brune    Logically Collective on SNES
1964534ebe21SPeter Brune 
1965534ebe21SPeter Brune    Input Parameters:
1966534ebe21SPeter Brune +  snes - the SNES context
1967365a6726SPeter Brune -  normschedule - the frequency of norm computation
1968534ebe21SPeter Brune 
1969517f1916SMatthew G. Knepley    Options Database Key:
197067b8a455SSatish Balay .  -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule
1971517f1916SMatthew G. Knepley 
1972534ebe21SPeter Brune    Notes:
1973365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1974534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1975534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1976a5b23f4aSJose E. Roman    (SNESNGS) and the like do not require the norm of the function to be computed, and therefore
1977534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1978534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1979534ebe21SPeter Brune    their solution.
1980534ebe21SPeter Brune 
1981534ebe21SPeter Brune    Level: developer
1982534ebe21SPeter Brune 
1983db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
1984534ebe21SPeter Brune @*/
1985365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1986534ebe21SPeter Brune {
1987534ebe21SPeter Brune   PetscFunctionBegin;
1988534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1989365a6726SPeter Brune   snes->normschedule = normschedule;
1990534ebe21SPeter Brune   PetscFunctionReturn(0);
1991534ebe21SPeter Brune }
1992534ebe21SPeter Brune 
1993534ebe21SPeter Brune /*@
1994a5b23f4aSJose E. Roman    SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring
1995534ebe21SPeter Brune    of the SNES method.
1996534ebe21SPeter Brune 
1997534ebe21SPeter Brune    Logically Collective on SNES
1998534ebe21SPeter Brune 
1999534ebe21SPeter Brune    Input Parameters:
2000534ebe21SPeter Brune +  snes - the SNES context
2001365a6726SPeter Brune -  normschedule - the type of the norm used
2002534ebe21SPeter Brune 
2003534ebe21SPeter Brune    Level: advanced
2004534ebe21SPeter Brune 
2005db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2006534ebe21SPeter Brune @*/
2007365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
2008534ebe21SPeter Brune {
2009534ebe21SPeter Brune   PetscFunctionBegin;
2010534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2011365a6726SPeter Brune   *normschedule = snes->normschedule;
2012534ebe21SPeter Brune   PetscFunctionReturn(0);
2013534ebe21SPeter Brune }
2014534ebe21SPeter Brune 
2015c5ce4427SMatthew G. Knepley /*@
2016c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
2017c5ce4427SMatthew G. Knepley 
2018c5ce4427SMatthew G. Knepley   Logically Collective on SNES
2019c5ce4427SMatthew G. Knepley 
2020c5ce4427SMatthew G. Knepley   Input Parameters:
2021c5ce4427SMatthew G. Knepley + snes - the SNES context
2022c5ce4427SMatthew G. Knepley 
2023c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
2024c5ce4427SMatthew G. Knepley 
2025c5ce4427SMatthew G. Knepley   Level: developer
2026c5ce4427SMatthew G. Knepley 
2027db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2028c5ce4427SMatthew G. Knepley @*/
2029c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
2030c5ce4427SMatthew G. Knepley {
2031c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
2032c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2033c5ce4427SMatthew G. Knepley   snes->norm = norm;
2034c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
2035c5ce4427SMatthew G. Knepley }
2036c5ce4427SMatthew G. Knepley 
2037c5ce4427SMatthew G. Knepley /*@
2038c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
2039c5ce4427SMatthew G. Knepley 
2040c5ce4427SMatthew G. Knepley   Not Collective
2041c5ce4427SMatthew G. Knepley 
2042c5ce4427SMatthew G. Knepley   Input Parameter:
2043c5ce4427SMatthew G. Knepley . snes - the SNES context
2044c5ce4427SMatthew G. Knepley 
2045c5ce4427SMatthew G. Knepley   Output Parameter:
2046c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
2047c5ce4427SMatthew G. Knepley 
2048c5ce4427SMatthew G. Knepley   Level: developer
2049c5ce4427SMatthew G. Knepley 
2050db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
2051c5ce4427SMatthew G. Knepley @*/
2052c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
2053c5ce4427SMatthew G. Knepley {
2054c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
2055c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2056dadcf809SJacob Faibussowitsch   PetscValidRealPointer(norm, 2);
2057c5ce4427SMatthew G. Knepley   *norm = snes->norm;
2058c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
2059c5ce4427SMatthew G. Knepley }
2060c5ce4427SMatthew G. Knepley 
2061c1e67a49SFande Kong /*@
2062c1e67a49SFande Kong   SNESGetUpdateNorm - Gets the last computed norm of the Newton update
2063c1e67a49SFande Kong 
2064c1e67a49SFande Kong   Not Collective
2065c1e67a49SFande Kong 
2066c1e67a49SFande Kong   Input Parameter:
2067c1e67a49SFande Kong . snes - the SNES context
2068c1e67a49SFande Kong 
2069c1e67a49SFande Kong   Output Parameter:
2070c1e67a49SFande Kong . ynorm - the last computed update norm
2071c1e67a49SFande Kong 
2072c1e67a49SFande Kong   Level: developer
2073c1e67a49SFande Kong 
2074db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`
2075c1e67a49SFande Kong @*/
2076c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2077c1e67a49SFande Kong {
2078c1e67a49SFande Kong   PetscFunctionBegin;
2079c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2080dadcf809SJacob Faibussowitsch   PetscValidRealPointer(ynorm, 2);
2081c1e67a49SFande Kong   *ynorm = snes->ynorm;
2082c1e67a49SFande Kong   PetscFunctionReturn(0);
2083c1e67a49SFande Kong }
2084c1e67a49SFande Kong 
2085c1e67a49SFande Kong /*@
20864591eaf2SFande Kong   SNESGetSolutionNorm - Gets the last computed norm of the solution
2087c1e67a49SFande Kong 
2088c1e67a49SFande Kong   Not Collective
2089c1e67a49SFande Kong 
2090c1e67a49SFande Kong   Input Parameter:
2091c1e67a49SFande Kong . snes - the SNES context
2092c1e67a49SFande Kong 
2093c1e67a49SFande Kong   Output Parameter:
2094c1e67a49SFande Kong . xnorm - the last computed solution norm
2095c1e67a49SFande Kong 
2096c1e67a49SFande Kong   Level: developer
2097c1e67a49SFande Kong 
2098db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()`
2099c1e67a49SFande Kong @*/
2100c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2101c1e67a49SFande Kong {
2102c1e67a49SFande Kong   PetscFunctionBegin;
2103c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2104dadcf809SJacob Faibussowitsch   PetscValidRealPointer(xnorm, 2);
2105c1e67a49SFande Kong   *xnorm = snes->xnorm;
2106c1e67a49SFande Kong   PetscFunctionReturn(0);
2107c1e67a49SFande Kong }
2108c1e67a49SFande Kong 
210947073ea2SPeter Brune /*@C
2110a5b23f4aSJose E. Roman    SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring
211147073ea2SPeter Brune    of the SNES method.
211247073ea2SPeter Brune 
211347073ea2SPeter Brune    Logically Collective on SNES
211447073ea2SPeter Brune 
211547073ea2SPeter Brune    Input Parameters:
211647073ea2SPeter Brune +  snes - the SNES context
211747073ea2SPeter Brune -  normschedule - the frequency of norm computation
211847073ea2SPeter Brune 
211947073ea2SPeter Brune    Notes:
212047073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
212147073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
212247073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
2123a5b23f4aSJose E. Roman    (SNESNGS) and the like do not require the norm of the function to be computed, and therefore
212447073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
212547073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
212647073ea2SPeter Brune    their solution.
212747073ea2SPeter Brune 
212847073ea2SPeter Brune    Level: developer
212947073ea2SPeter Brune 
2130db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
213147073ea2SPeter Brune @*/
213247073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
213347073ea2SPeter Brune {
213447073ea2SPeter Brune   PetscFunctionBegin;
213547073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
213647073ea2SPeter Brune   snes->functype = type;
213747073ea2SPeter Brune   PetscFunctionReturn(0);
213847073ea2SPeter Brune }
213947073ea2SPeter Brune 
214047073ea2SPeter Brune /*@C
2141a5b23f4aSJose E. Roman    SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring
214247073ea2SPeter Brune    of the SNES method.
214347073ea2SPeter Brune 
214447073ea2SPeter Brune    Logically Collective on SNES
214547073ea2SPeter Brune 
214647073ea2SPeter Brune    Input Parameters:
214747073ea2SPeter Brune +  snes - the SNES context
214847073ea2SPeter Brune -  normschedule - the type of the norm used
214947073ea2SPeter Brune 
215047073ea2SPeter Brune    Level: advanced
215147073ea2SPeter Brune 
2152db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule`
215347073ea2SPeter Brune @*/
215447073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
215547073ea2SPeter Brune {
215647073ea2SPeter Brune   PetscFunctionBegin;
215747073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
215847073ea2SPeter Brune   *type = snes->functype;
2159534ebe21SPeter Brune   PetscFunctionReturn(0);
2160534ebe21SPeter Brune }
2161534ebe21SPeter Brune 
2162bf388a1fSBarry Smith /*MC
2163be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
2164bf388a1fSBarry Smith 
2165bf388a1fSBarry Smith      Synopsis:
2166aaa7dc30SBarry Smith      #include <petscsnes.h>
2167be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
2168bf388a1fSBarry Smith 
21691843f636SBarry Smith      Collective on snes
21701843f636SBarry Smith 
21711843f636SBarry Smith      Input Parameters:
2172bf388a1fSBarry Smith +  X   - solution vector
2173bf388a1fSBarry Smith .  B   - RHS vector
2174bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
2175bf388a1fSBarry Smith 
21761843f636SBarry Smith      Output Parameter:
21771843f636SBarry Smith .  X   - solution vector
21781843f636SBarry Smith 
2179878cb397SSatish Balay    Level: intermediate
2180878cb397SSatish Balay 
2181db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetNGS()`
2182bf388a1fSBarry Smith M*/
2183bf388a1fSBarry Smith 
2184c79ef259SPeter Brune /*@C
2185be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2186c79ef259SPeter Brune    use with composed nonlinear solvers.
2187c79ef259SPeter Brune 
2188c79ef259SPeter Brune    Input Parameters:
2189c79ef259SPeter Brune +  snes   - the SNES context
2190be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
2191c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
21920298fd71SBarry Smith             smoother evaluation routine (may be NULL)
2193c79ef259SPeter Brune 
2194c79ef259SPeter Brune    Notes:
2195be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
2196c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
2197c79ef259SPeter Brune 
2198d28543b3SPeter Brune    Level: intermediate
2199c79ef259SPeter Brune 
2200db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeNGS()`
2201c79ef259SPeter Brune @*/
2202be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
22036cab3a1bSJed Brown {
22046cab3a1bSJed Brown   DM             dm;
22056cab3a1bSJed Brown 
2206646217ecSPeter Brune   PetscFunctionBegin;
22076cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22089566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
22099566063dSJacob Faibussowitsch   PetscCall(DMSNESSetNGS(dm,f,ctx));
2210646217ecSPeter Brune   PetscFunctionReturn(0);
2211646217ecSPeter Brune }
2212646217ecSPeter Brune 
2213bbc1464cSBarry Smith /*
2214bbc1464cSBarry Smith      This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be
2215bbc1464cSBarry Smith    changed during the KSPSolve()
2216bbc1464cSBarry Smith */
2217bbc1464cSBarry Smith PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx)
2218bbc1464cSBarry Smith {
2219bbc1464cSBarry Smith   DM             dm;
2220bbc1464cSBarry Smith   DMSNES         sdm;
2221bbc1464cSBarry Smith 
2222bbc1464cSBarry Smith   PetscFunctionBegin;
22239566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
22249566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
22255f80ce2aSJacob Faibussowitsch   PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
2226bbc1464cSBarry Smith   /*  A(x)*x - b(x) */
2227bbc1464cSBarry Smith   if (sdm->ops->computepfunction) {
2228bbc1464cSBarry Smith     PetscStackPush("SNES Picard user function");
22299566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx));
2230bbc1464cSBarry Smith     PetscStackPop;
22319566063dSJacob Faibussowitsch     PetscCall(VecScale(f,-1.0));
2232bbc1464cSBarry Smith     if (!snes->picard) {
22330df40c35SBarry Smith       /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */
22349566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard));
2235bbc1464cSBarry Smith     }
2236bbc1464cSBarry Smith     PetscStackPush("SNES Picard user Jacobian");
22379566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx));
2238bbc1464cSBarry Smith     PetscStackPop;
22399566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(snes->picard,x,f,f));
2240bbc1464cSBarry Smith   } else {
2241bbc1464cSBarry Smith     PetscStackPush("SNES Picard user Jacobian");
22429566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx));
2243bbc1464cSBarry Smith     PetscStackPop;
22449566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->picard,x,f));
2245bbc1464cSBarry Smith   }
2246bbc1464cSBarry Smith   PetscFunctionReturn(0);
2247bbc1464cSBarry Smith }
2248bbc1464cSBarry Smith 
224925acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
22508b0a5094SBarry Smith {
2251e03ab78fSPeter Brune   DM             dm;
2252942e3340SBarry Smith   DMSNES         sdm;
22536cab3a1bSJed Brown 
22548b0a5094SBarry Smith   PetscFunctionBegin;
22559566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
22569566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
22575f80ce2aSJacob Faibussowitsch   PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
22588b0a5094SBarry Smith   /*  A(x)*x - b(x) */
2259bbc1464cSBarry Smith   if (sdm->ops->computepfunction) {
226025acbd8eSLisandro Dalcin     PetscStackPush("SNES Picard user function");
22619566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx));
226225acbd8eSLisandro Dalcin     PetscStackPop;
22639566063dSJacob Faibussowitsch     PetscCall(VecScale(f,-1.0));
226425acbd8eSLisandro Dalcin     PetscStackPush("SNES Picard user Jacobian");
22659566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx));
226625acbd8eSLisandro Dalcin     PetscStackPop;
22679566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(snes->jacobian_pre,x,f,f));
2268bbc1464cSBarry Smith   } else {
2269bbc1464cSBarry Smith     PetscStackPush("SNES Picard user Jacobian");
22709566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx));
2271bbc1464cSBarry Smith     PetscStackPop;
22729566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->jacobian_pre,x,f));
2273bbc1464cSBarry Smith   }
22748b0a5094SBarry Smith   PetscFunctionReturn(0);
22758b0a5094SBarry Smith }
22768b0a5094SBarry Smith 
227725acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
22788b0a5094SBarry Smith {
22798b0a5094SBarry Smith   PetscFunctionBegin;
2280e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
2281bbc1464cSBarry Smith   /* must assembly if matrix-free to get the last SNES solution */
22829566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY));
22839566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY));
22848b0a5094SBarry Smith   PetscFunctionReturn(0);
22858b0a5094SBarry Smith }
22868b0a5094SBarry Smith 
22878b0a5094SBarry Smith /*@C
2288bbc1464cSBarry Smith    SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization)
22898b0a5094SBarry Smith 
22908b0a5094SBarry Smith    Logically Collective on SNES
22918b0a5094SBarry Smith 
22928b0a5094SBarry Smith    Input Parameters:
22938b0a5094SBarry Smith +  snes - the SNES context
22946b7fb656SBarry Smith .  r - vector to store function values, may be NULL
22956b7fb656SBarry Smith .  bp - function evaluation routine, may be NULL
22966b7fb656SBarry Smith .  Amat - matrix with which A(x) x - bp(x) - b is to be computed
2297e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
22986b7fb656SBarry Smith .  J  - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence
22996b7fb656SBarry Smith -  ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL)
23008b0a5094SBarry Smith 
23018b0a5094SBarry Smith    Notes:
23026b7fb656SBarry Smith     It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use
2303f450aa47SBarry 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.
2304f450aa47SBarry Smith 
23058b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
23068b0a5094SBarry Smith 
23076b7fb656SBarry 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}
23086b7fb656SBarry 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.
23098b0a5094SBarry Smith 
23108b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
23118b0a5094SBarry Smith 
23120d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
23136b7fb656SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b
23148b0a5094SBarry Smith 
23158b0a5094SBarry 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
23168b0a5094SBarry 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
23178b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
23188b0a5094SBarry Smith 
23196b7fb656SBarry 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.
23206b7fb656SBarry Smith 
23216b7fb656SBarry 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.
23226b7fb656SBarry Smith 
23236b7fb656SBarry 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
23246b7fb656SBarry 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
23256b7fb656SBarry 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.
23266b7fb656SBarry Smith    See the commment in src/snes/tutorials/ex15.c.
2327bbc1464cSBarry Smith 
2328f450aa47SBarry Smith    Level: intermediate
23298b0a5094SBarry Smith 
2330db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction`
23318b0a5094SBarry Smith @*/
2332bbc1464cSBarry Smith 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)
23338b0a5094SBarry Smith {
2334e03ab78fSPeter Brune   DM             dm;
2335e03ab78fSPeter Brune 
23368b0a5094SBarry Smith   PetscFunctionBegin;
23378b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23389566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
23399566063dSJacob Faibussowitsch   PetscCall(DMSNESSetPicard(dm,bp,J,ctx));
23409566063dSJacob Faibussowitsch   PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx));
23419566063dSJacob Faibussowitsch   PetscCall(SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx));
23429566063dSJacob Faibussowitsch   PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx));
23438b0a5094SBarry Smith   PetscFunctionReturn(0);
23448b0a5094SBarry Smith }
23458b0a5094SBarry Smith 
23467971a8bfSPeter Brune /*@C
23477971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
23487971a8bfSPeter Brune 
23497971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
23507971a8bfSPeter Brune 
23517971a8bfSPeter Brune    Input Parameter:
23527971a8bfSPeter Brune .  snes - the SNES context
23537971a8bfSPeter Brune 
2354d8d19677SJose E. Roman    Output Parameters:
23550298fd71SBarry Smith +  r - the function (or NULL)
2356f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
2357e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2358e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2359f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
23600298fd71SBarry Smith -  ctx - the function context (or NULL)
23617971a8bfSPeter Brune 
23627971a8bfSPeter Brune    Level: advanced
23637971a8bfSPeter Brune 
2364db781477SPatrick Sanan .seealso: `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction`
23657971a8bfSPeter Brune @*/
2366d1e9a80fSBarry Smith 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)
23677971a8bfSPeter Brune {
23687971a8bfSPeter Brune   DM             dm;
23697971a8bfSPeter Brune 
23707971a8bfSPeter Brune   PetscFunctionBegin;
23717971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23729566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,r,NULL,NULL));
23739566063dSJacob Faibussowitsch   PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL));
23749566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
23759566063dSJacob Faibussowitsch   PetscCall(DMSNESGetPicard(dm,f,J,ctx));
23767971a8bfSPeter Brune   PetscFunctionReturn(0);
23777971a8bfSPeter Brune }
23787971a8bfSPeter Brune 
2379d25893d9SBarry Smith /*@C
2380d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2381d25893d9SBarry Smith 
2382d25893d9SBarry Smith    Logically Collective on SNES
2383d25893d9SBarry Smith 
2384d25893d9SBarry Smith    Input Parameters:
2385d25893d9SBarry Smith +  snes - the SNES context
2386d25893d9SBarry Smith .  func - function evaluation routine
2387d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
23880298fd71SBarry Smith          function evaluation routine (may be NULL)
2389d25893d9SBarry Smith 
2390d25893d9SBarry Smith    Calling sequence of func:
2391d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2392d25893d9SBarry Smith 
2393d25893d9SBarry Smith .  f - function vector
2394d25893d9SBarry Smith -  ctx - optional user-defined function context
2395d25893d9SBarry Smith 
2396d25893d9SBarry Smith    Level: intermediate
2397d25893d9SBarry Smith 
2398db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`
2399d25893d9SBarry Smith @*/
2400d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2401d25893d9SBarry Smith {
2402d25893d9SBarry Smith   PetscFunctionBegin;
2403d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2404d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2405d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2406d25893d9SBarry Smith   PetscFunctionReturn(0);
2407d25893d9SBarry Smith }
2408d25893d9SBarry Smith 
24093ab0aad5SBarry Smith /* --------------------------------------------------------------- */
24101096aae1SMatthew Knepley /*@C
24111096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
24121096aae1SMatthew Knepley    it assumes a zero right hand side.
24131096aae1SMatthew Knepley 
24143f9fe445SBarry Smith    Logically Collective on SNES
24151096aae1SMatthew Knepley 
24161096aae1SMatthew Knepley    Input Parameter:
24171096aae1SMatthew Knepley .  snes - the SNES context
24181096aae1SMatthew Knepley 
24191096aae1SMatthew Knepley    Output Parameter:
24200298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
24211096aae1SMatthew Knepley 
24221096aae1SMatthew Knepley    Level: intermediate
24231096aae1SMatthew Knepley 
2424db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()`
24251096aae1SMatthew Knepley @*/
24267087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
24271096aae1SMatthew Knepley {
24281096aae1SMatthew Knepley   PetscFunctionBegin;
24290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
24301096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
243185385478SLisandro Dalcin   *rhs = snes->vec_rhs;
24321096aae1SMatthew Knepley   PetscFunctionReturn(0);
24331096aae1SMatthew Knepley }
24341096aae1SMatthew Knepley 
24359b94acceSBarry Smith /*@
2436bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
24379b94acceSBarry Smith 
2438c7afd0dbSLois Curfman McInnes    Collective on SNES
2439c7afd0dbSLois Curfman McInnes 
24409b94acceSBarry Smith    Input Parameters:
2441c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2442c7afd0dbSLois Curfman McInnes -  x - input vector
24439b94acceSBarry Smith 
24449b94acceSBarry Smith    Output Parameter:
24453638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
24469b94acceSBarry Smith 
24471bffabb2SLois Curfman McInnes    Notes:
244836851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
2449bbc1464cSBarry Smith    implementations, so users would not generally call this routine themselves.
245036851e7fSLois Curfman McInnes 
245136851e7fSLois Curfman McInnes    Level: developer
245236851e7fSLois Curfman McInnes 
2453db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()`
24549b94acceSBarry Smith @*/
24557087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
24569b94acceSBarry Smith {
24576cab3a1bSJed Brown   DM             dm;
2458942e3340SBarry Smith   DMSNES         sdm;
24599b94acceSBarry Smith 
24603a40ed3dSBarry Smith   PetscFunctionBegin;
24610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
24620700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
24630700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2464c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2465c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
24669566063dSJacob Faibussowitsch   PetscCall(VecValidValues(x,2,PETSC_TRUE));
2467184914b5SBarry Smith 
24689566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
24699566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
247032f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
247194db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
24729566063dSJacob Faibussowitsch       PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0));
247394db00ebSBarry Smith     }
24749566063dSJacob Faibussowitsch     PetscCall(VecLockReadPush(x));
2475d64ed03dSBarry Smith     PetscStackPush("SNES user function");
24768ddeebeaSSteve Benbow     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
24778ddeebeaSSteve Benbow     snes->domainerror = PETSC_FALSE;
24789566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computefunction)(snes,x,y,sdm->functionctx));
2479d64ed03dSBarry Smith     PetscStackPop;
24809566063dSJacob Faibussowitsch     PetscCall(VecLockReadPop(x));
248194db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
24829566063dSJacob Faibussowitsch       PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0));
248394db00ebSBarry Smith     }
2484c90fad12SPeter Brune   } else if (snes->vec_rhs) {
24859566063dSJacob Faibussowitsch     PetscCall(MatMult(snes->jacobian, x, y));
2486644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
248785385478SLisandro Dalcin   if (snes->vec_rhs) {
24889566063dSJacob Faibussowitsch     PetscCall(VecAXPY(y,-1.0,snes->vec_rhs));
24893ab0aad5SBarry Smith   }
2490ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2491422a814eSBarry Smith   /*
2492422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2493422a814eSBarry Smith      propagate the value to all processes
2494422a814eSBarry Smith   */
2495422a814eSBarry Smith   if (snes->domainerror) {
24969566063dSJacob Faibussowitsch     PetscCall(VecSetInf(y));
2497422a814eSBarry Smith   }
24983a40ed3dSBarry Smith   PetscFunctionReturn(0);
24999b94acceSBarry Smith }
25009b94acceSBarry Smith 
2501c79ef259SPeter Brune /*@
2502bbc1464cSBarry Smith    SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction().
2503bbc1464cSBarry Smith 
2504bbc1464cSBarry Smith    Collective on SNES
2505bbc1464cSBarry Smith 
2506bbc1464cSBarry Smith    Input Parameters:
2507bbc1464cSBarry Smith +  snes - the SNES context
2508bbc1464cSBarry Smith -  x - input vector
2509bbc1464cSBarry Smith 
2510bbc1464cSBarry Smith    Output Parameter:
2511bbc1464cSBarry Smith .  y - function vector, as set by SNESSetMFFunction()
2512bbc1464cSBarry Smith 
2513bbc1464cSBarry Smith    Notes:
2514bbc1464cSBarry Smith        SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF()
2515bbc1464cSBarry Smith    so users would not generally call this routine themselves.
2516bbc1464cSBarry Smith 
2517bbc1464cSBarry Smith        Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve()
2518bbc1464cSBarry Smith     while SNESComputeFunction() does. As such, this routine cannot be used with  MatMFFDSetBase() with a provided F function value even if it applies the
2519bbc1464cSBarry 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.
2520bbc1464cSBarry Smith 
2521bbc1464cSBarry Smith    Level: developer
2522bbc1464cSBarry Smith 
2523db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF`
2524bbc1464cSBarry Smith @*/
2525bbc1464cSBarry Smith PetscErrorCode  SNESComputeMFFunction(SNES snes,Vec x,Vec y)
2526bbc1464cSBarry Smith {
2527bbc1464cSBarry Smith   DM             dm;
2528bbc1464cSBarry Smith   DMSNES         sdm;
2529bbc1464cSBarry Smith 
2530bbc1464cSBarry Smith   PetscFunctionBegin;
2531bbc1464cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2532bbc1464cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2533bbc1464cSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2534bbc1464cSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2535bbc1464cSBarry Smith   PetscCheckSameComm(snes,1,y,3);
25369566063dSJacob Faibussowitsch   PetscCall(VecValidValues(x,2,PETSC_TRUE));
2537bbc1464cSBarry Smith 
25389566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
25399566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
25409566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0));
25419566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(x));
2542bbc1464cSBarry Smith   PetscStackPush("SNES user function");
2543bbc1464cSBarry Smith   /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
2544bbc1464cSBarry Smith   snes->domainerror = PETSC_FALSE;
25459566063dSJacob Faibussowitsch   PetscCall((*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx));
2546bbc1464cSBarry Smith   PetscStackPop;
25479566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(x));
25489566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0));
2549bbc1464cSBarry Smith   snes->nfuncs++;
2550bbc1464cSBarry Smith   /*
2551bbc1464cSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2552bbc1464cSBarry Smith      propagate the value to all processes
2553bbc1464cSBarry Smith   */
2554bbc1464cSBarry Smith   if (snes->domainerror) {
25559566063dSJacob Faibussowitsch     PetscCall(VecSetInf(y));
2556bbc1464cSBarry Smith   }
2557bbc1464cSBarry Smith   PetscFunctionReturn(0);
2558bbc1464cSBarry Smith }
2559bbc1464cSBarry Smith 
2560bbc1464cSBarry Smith /*@
2561be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2562c79ef259SPeter Brune 
2563c79ef259SPeter Brune    Collective on SNES
2564c79ef259SPeter Brune 
2565c79ef259SPeter Brune    Input Parameters:
2566c79ef259SPeter Brune +  snes - the SNES context
2567c79ef259SPeter Brune .  x - input vector
2568c79ef259SPeter Brune -  b - rhs vector
2569c79ef259SPeter Brune 
2570c79ef259SPeter Brune    Output Parameter:
2571c79ef259SPeter Brune .  x - new solution vector
2572c79ef259SPeter Brune 
2573c79ef259SPeter Brune    Notes:
2574be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2575c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2576c79ef259SPeter Brune    themselves.
2577c79ef259SPeter Brune 
2578c79ef259SPeter Brune    Level: developer
2579c79ef259SPeter Brune 
2580db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESComputeFunction()`
2581c79ef259SPeter Brune @*/
2582be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2583646217ecSPeter Brune {
25846cab3a1bSJed Brown   DM             dm;
2585942e3340SBarry Smith   DMSNES         sdm;
2586646217ecSPeter Brune 
2587646217ecSPeter Brune   PetscFunctionBegin;
2588646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2589064a246eSJacob Faibussowitsch   PetscValidHeaderSpecific(x,VEC_CLASSID,3);
2590064a246eSJacob Faibussowitsch   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
2591064a246eSJacob Faibussowitsch   PetscCheckSameComm(snes,1,x,3);
2592064a246eSJacob Faibussowitsch   if (b) PetscCheckSameComm(snes,1,b,2);
25939566063dSJacob Faibussowitsch   if (b) PetscCall(VecValidValues(b,2,PETSC_TRUE));
25949566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_NGSEval,snes,x,b,0));
25959566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
25969566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
259722c6f798SBarry Smith   if (sdm->ops->computegs) {
25989566063dSJacob Faibussowitsch     if (b) PetscCall(VecLockReadPush(b));
2599be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
26009566063dSJacob Faibussowitsch     PetscCall((*sdm->ops->computegs)(snes,x,b,sdm->gsctx));
2601646217ecSPeter Brune     PetscStackPop;
26029566063dSJacob Faibussowitsch     if (b) PetscCall(VecLockReadPop(b));
2603be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
26049566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_NGSEval,snes,x,b,0));
2605646217ecSPeter Brune   PetscFunctionReturn(0);
2606646217ecSPeter Brune }
2607646217ecSPeter Brune 
2608e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes)
2609e885f1abSBarry Smith {
261012837594SBarry Smith   Mat               A,B,C,D,jacobian;
2611e885f1abSBarry Smith   Vec               x = snes->vec_sol,f = snes->vec_func;
2612e885f1abSBarry Smith   PetscReal         nrm,gnorm;
261381e7118cSBarry Smith   PetscReal         threshold = 1.e-5;
26140e276705SLisandro Dalcin   MatType           mattype;
2615e885f1abSBarry Smith   PetscInt          m,n,M,N;
2616e885f1abSBarry Smith   void              *functx;
26172cd624f9SStefano Zampini   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose;
26183325ff46SBarry Smith   PetscViewer       viewer,mviewer;
2619e885f1abSBarry Smith   MPI_Comm          comm;
2620e885f1abSBarry Smith   PetscInt          tabs;
262112837594SBarry Smith   static PetscBool  directionsprinted = PETSC_FALSE;
26223325ff46SBarry Smith   PetscViewerFormat format;
2623e885f1abSBarry Smith 
2624e885f1abSBarry Smith   PetscFunctionBegin;
2625d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)snes);
26269566063dSJacob Faibussowitsch   PetscCall(PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test));
26279566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL));
26289566063dSJacob Faibussowitsch   PetscCall(PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print));
262918d89885SKarl Rupp   if (!complete_print) {
26309566063dSJacob Faibussowitsch     PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL));
26319566063dSJacob Faibussowitsch     PetscCall(PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print));
263218d89885SKarl Rupp   }
263318d89885SKarl Rupp   /* for compatibility with PETSc 3.9 and older. */
26349566063dSJacob Faibussowitsch   PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)"));
26359566063dSJacob 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));
2636d0609cedSBarry Smith   PetscOptionsEnd();
2637e885f1abSBarry Smith   if (!test) PetscFunctionReturn(0);
2638e885f1abSBarry Smith 
26399566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)snes,&comm));
26409566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetStdout(comm,&viewer));
26419566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIGetTab(viewer, &tabs));
26429566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel));
26439566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n"));
264412837594SBarry Smith   if (!complete_print && !directionsprinted) {
26459566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n"));
26469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n"));
264712837594SBarry Smith   }
264812837594SBarry Smith   if (!directionsprinted) {
26499566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n"));
26509566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n"));
265112837594SBarry Smith     directionsprinted = PETSC_TRUE;
2652e885f1abSBarry Smith   }
26533325ff46SBarry Smith   if (complete_print) {
26549566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(mviewer,format));
2655e885f1abSBarry Smith   }
2656e885f1abSBarry Smith 
26579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg));
265812837594SBarry Smith   if (!flg) jacobian = snes->jacobian;
265912837594SBarry Smith   else jacobian = snes->jacobian_pre;
266012837594SBarry Smith 
2661a82339d0SMatthew G. Knepley   if (!x) {
26629566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(jacobian, &x, NULL));
2663a82339d0SMatthew G. Knepley   } else {
26649566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject) x));
2665a82339d0SMatthew G. Knepley   }
2666a82339d0SMatthew G. Knepley   if (!f) {
26679566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &f));
2668a82339d0SMatthew G. Knepley   } else {
26699566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject) f));
2670a82339d0SMatthew G. Knepley   }
2671a82339d0SMatthew G. Knepley   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
26729566063dSJacob Faibussowitsch   PetscCall(SNESComputeFunction(snes,x,f));
26739566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&f));
26749566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose));
267512837594SBarry Smith   while (jacobian) {
26762cd624f9SStefano Zampini     Mat JT = NULL, Jsave = NULL;
26772cd624f9SStefano Zampini 
26782cd624f9SStefano Zampini     if (istranspose) {
26799566063dSJacob Faibussowitsch       PetscCall(MatCreateTranspose(jacobian,&JT));
26802cd624f9SStefano Zampini       Jsave = jacobian;
26812cd624f9SStefano Zampini       jacobian = JT;
26822cd624f9SStefano Zampini     }
26839566063dSJacob Faibussowitsch     PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,""));
268412837594SBarry Smith     if (flg) {
268512837594SBarry Smith       A    = jacobian;
26869566063dSJacob Faibussowitsch       PetscCall(PetscObjectReference((PetscObject)A));
268712837594SBarry Smith     } else {
26889566063dSJacob Faibussowitsch       PetscCall(MatComputeOperator(jacobian,MATAIJ,&A));
268912837594SBarry Smith     }
2690e885f1abSBarry Smith 
26919566063dSJacob Faibussowitsch     PetscCall(MatGetType(A,&mattype));
26929566063dSJacob Faibussowitsch     PetscCall(MatGetSize(A,&M,&N));
26939566063dSJacob Faibussowitsch     PetscCall(MatGetLocalSize(A,&m,&n));
26949566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
26959566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,mattype));
26969566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,M,N));
26979566063dSJacob Faibussowitsch     PetscCall(MatSetBlockSizesFromMats(B,A,A));
26989566063dSJacob Faibussowitsch     PetscCall(MatSetUp(B));
26999566063dSJacob Faibussowitsch     PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
2700e885f1abSBarry Smith 
27019566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes,NULL,NULL,&functx));
27029566063dSJacob Faibussowitsch     PetscCall(SNESComputeJacobianDefault(snes,x,B,B,functx));
270312837594SBarry Smith 
27049566063dSJacob Faibussowitsch     PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D));
27059566063dSJacob Faibussowitsch     PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN));
27069566063dSJacob Faibussowitsch     PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm));
27079566063dSJacob Faibussowitsch     PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm));
27089566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&D));
270912837594SBarry Smith     if (!gnorm) gnorm = 1; /* just in case */
27109566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm));
271112837594SBarry Smith 
2712e885f1abSBarry Smith     if (complete_print) {
27139566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n"));
27149566063dSJacob Faibussowitsch       PetscCall(MatView(A,mviewer));
27159566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n"));
27169566063dSJacob Faibussowitsch       PetscCall(MatView(B,mviewer));
2717e885f1abSBarry Smith     }
2718e885f1abSBarry Smith 
2719df10fb39SFande Kong     if (threshold_print || complete_print) {
2720e885f1abSBarry Smith       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
2721e885f1abSBarry Smith       PetscScalar       *cvals;
2722e885f1abSBarry Smith       const PetscInt    *bcols;
2723e885f1abSBarry Smith       const PetscScalar *bvals;
2724e885f1abSBarry Smith 
27259566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C));
27269566063dSJacob Faibussowitsch       PetscCall(MatSetType(C,mattype));
27279566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(C,m,n,M,N));
27289566063dSJacob Faibussowitsch       PetscCall(MatSetBlockSizesFromMats(C,A,A));
27299566063dSJacob Faibussowitsch       PetscCall(MatSetUp(C));
27309566063dSJacob Faibussowitsch       PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE));
27310e276705SLisandro Dalcin 
27329566063dSJacob Faibussowitsch       PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN));
27339566063dSJacob Faibussowitsch       PetscCall(MatGetOwnershipRange(B,&Istart,&Iend));
2734e885f1abSBarry Smith 
2735e885f1abSBarry Smith       for (row = Istart; row < Iend; row++) {
27369566063dSJacob Faibussowitsch         PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals));
27379566063dSJacob Faibussowitsch         PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals));
2738e885f1abSBarry Smith         for (j = 0, cncols = 0; j < bncols; j++) {
273923a52b1dSBarry Smith           if (PetscAbsScalar(bvals[j]) > threshold) {
2740e885f1abSBarry Smith             ccols[cncols] = bcols[j];
2741e885f1abSBarry Smith             cvals[cncols] = bvals[j];
2742e885f1abSBarry Smith             cncols += 1;
2743e885f1abSBarry Smith           }
2744e885f1abSBarry Smith         }
2745e885f1abSBarry Smith         if (cncols) {
27469566063dSJacob Faibussowitsch           PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES));
2747e885f1abSBarry Smith         }
27489566063dSJacob Faibussowitsch         PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals));
27499566063dSJacob Faibussowitsch         PetscCall(PetscFree2(ccols,cvals));
2750e885f1abSBarry Smith       }
27519566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY));
27529566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY));
27539566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold));
27549566063dSJacob Faibussowitsch       PetscCall(MatView(C,complete_print ? mviewer : viewer));
27559566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&C));
2756e885f1abSBarry Smith     }
27579566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&A));
27589566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&B));
27599566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&JT));
27602cd624f9SStefano Zampini     if (Jsave) jacobian = Jsave;
276112837594SBarry Smith     if (jacobian != snes->jacobian_pre) {
276212837594SBarry Smith       jacobian = snes->jacobian_pre;
27639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n"));
276412837594SBarry Smith     }
276512837594SBarry Smith     else jacobian = NULL;
276612837594SBarry Smith   }
27679566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&x));
27683325ff46SBarry Smith   if (complete_print) {
27699566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(mviewer));
27703325ff46SBarry Smith   }
27719566063dSJacob Faibussowitsch   if (mviewer) PetscCall(PetscViewerDestroy(&mviewer));
27729566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIISetTab(viewer,tabs));
2773e885f1abSBarry Smith   PetscFunctionReturn(0);
2774e885f1abSBarry Smith }
2775e885f1abSBarry Smith 
277662fef451SLois Curfman McInnes /*@
2777bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
277862fef451SLois Curfman McInnes 
2779d083f849SBarry Smith    Collective on SNES
2780c7afd0dbSLois Curfman McInnes 
278162fef451SLois Curfman McInnes    Input Parameters:
2782c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2783c7afd0dbSLois Curfman McInnes -  x - input vector
278462fef451SLois Curfman McInnes 
278562fef451SLois Curfman McInnes    Output Parameters:
2786c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2787d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2788fee21e36SBarry Smith 
2789e35cf81dSBarry Smith   Options Database Keys:
279067b8a455SSatish Balay +    -snes_lag_preconditioner <lag> - how often to rebuild preconditioner
279167b8a455SSatish Balay .    -snes_lag_jacobian <lag> - how often to rebuild Jacobian
2792455a5933SJed 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.
2793455a5933SJed 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
2794693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2795693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2796693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
27974c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
279894d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2799a5b23f4aSJose E. Roman .    -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences
2800c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2801c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2802c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2803a5b23f4aSJose E. Roman .    -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences
2804a5b23f4aSJose E. Roman -    -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences
2805c01495d3SJed Brown 
280662fef451SLois Curfman McInnes    Notes:
280762fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
280862fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
280962fef451SLois Curfman McInnes 
281095452b02SPatrick Sanan    Developer Notes:
281195452b02SPatrick 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
2812e885f1abSBarry Smith       for with the SNESType of test that has been removed.
2813e885f1abSBarry Smith 
281436851e7fSLois Curfman McInnes    Level: developer
281536851e7fSLois Curfman McInnes 
2816db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()`
281762fef451SLois Curfman McInnes @*/
2818d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
28199b94acceSBarry Smith {
2820ace3abfcSBarry Smith   PetscBool      flag;
28216cab3a1bSJed Brown   DM             dm;
2822942e3340SBarry Smith   DMSNES         sdm;
2823e0e3a89bSBarry Smith   KSP            ksp;
28243a40ed3dSBarry Smith 
28253a40ed3dSBarry Smith   PetscFunctionBegin;
28260700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28270700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2828c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
28299566063dSJacob Faibussowitsch   PetscCall(VecValidValues(X,2,PETSC_TRUE));
28309566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
28319566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
28323232da50SPeter Brune 
28335f80ce2aSJacob Faibussowitsch   PetscCheck(sdm->ops->computejacobian,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2834ebd3b9afSBarry Smith 
2835ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2836ebd3b9afSBarry Smith 
2837fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2838fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2839f5af7f23SKarl Rupp 
28409566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n"));
2841fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
28429566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n"));
28439566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag));
2844ebd3b9afSBarry Smith     if (flag) {
28459566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
28469566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2847ebd3b9afSBarry Smith     }
2848e35cf81dSBarry Smith     PetscFunctionReturn(0);
284937ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
285063a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagjacobian,snes->iter));
28519566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag));
2852ebd3b9afSBarry Smith     if (flag) {
28539566063dSJacob Faibussowitsch       PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
28549566063dSJacob Faibussowitsch       PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2855ebd3b9afSBarry Smith     }
2856e35cf81dSBarry Smith     PetscFunctionReturn(0);
2857e35cf81dSBarry Smith   }
2858efd4aadfSBarry Smith   if (snes->npc && snes->npcside == PC_LEFT) {
28599566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY));
28609566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY));
2861d728fb7dSPeter Brune     PetscFunctionReturn(0);
2862d728fb7dSPeter Brune   }
2863e35cf81dSBarry Smith 
28649566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B));
28659566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(X));
2866d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
28679566063dSJacob Faibussowitsch   PetscCall((*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx));
2868d64ed03dSBarry Smith   PetscStackPop;
28699566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(X));
28709566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B));
287128d58a37SPierre Jolivet 
287228d58a37SPierre Jolivet   /* attach latest linearization point to the preconditioning matrix */
28739566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X));
2874a8054027SBarry Smith 
2875e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
28769566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,&ksp));
28773b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
28789566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n"));
28799566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE));
28803b4f5425SBarry Smith     snes->lagpreconditioner = -1;
28813b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
28829566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is -1\n"));
28839566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE));
288437ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
288563a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagpreconditioner,snes->iter));
28869566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE));
2887d1e9a80fSBarry Smith   } else {
28889566063dSJacob Faibussowitsch     PetscCall(PetscInfo(snes,"Rebuilding preconditioner\n"));
28899566063dSJacob Faibussowitsch     PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE));
2890a8054027SBarry Smith   }
2891a8054027SBarry Smith 
28929566063dSJacob Faibussowitsch   PetscCall(SNESTestJacobian(snes));
28936d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
289494ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
289594ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2896693365a8SJed Brown   {
2897693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
28989566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag));
28999566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw));
29009566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour));
29019566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator));
2902693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
29030298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2904693365a8SJed Brown       PetscViewer  vdraw,vstdout;
29056b3a5b13SJed Brown       PetscBool    flg;
2906693365a8SJed Brown       if (flag_operator) {
29079566063dSJacob Faibussowitsch         PetscCall(MatComputeOperator(A,MATAIJ,&Bexp_mine));
2908693365a8SJed Brown         Bexp = Bexp_mine;
2909693365a8SJed Brown       } else {
2910693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
29119566063dSJacob Faibussowitsch         PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,""));
291294ab13aaSBarry Smith         if (flg) Bexp = B;
2913693365a8SJed Brown         else {
2914693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
29159566063dSJacob Faibussowitsch           PetscCall(MatComputeOperator(B,MATAIJ,&Bexp_mine));
2916693365a8SJed Brown           Bexp = Bexp_mine;
2917693365a8SJed Brown         }
2918693365a8SJed Brown       }
29199566063dSJacob Faibussowitsch       PetscCall(MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp));
29209566063dSJacob Faibussowitsch       PetscCall(SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL));
29219566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout));
2922693365a8SJed Brown       if (flag_draw || flag_contour) {
29239566063dSJacob Faibussowitsch         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw));
29249566063dSJacob Faibussowitsch         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
29250298fd71SBarry Smith       } else vdraw = NULL;
29269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian"));
29279566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(Bexp,vstdout));
29289566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(Bexp,vdraw));
29299566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n"));
29309566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(FDexp,vstdout));
29319566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(FDexp,vdraw));
29329566063dSJacob Faibussowitsch       PetscCall(MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN));
29339566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n"));
29349566063dSJacob Faibussowitsch       if (flag) PetscCall(MatView(FDexp,vstdout));
2935693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
29369566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
29379566063dSJacob Faibussowitsch         PetscCall(MatView(FDexp,vdraw));
29389566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(vdraw));
2939693365a8SJed Brown       }
29409566063dSJacob Faibussowitsch       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
29419566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&vdraw));
29429566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bexp_mine));
29439566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&FDexp));
2944693365a8SJed Brown     }
2945693365a8SJed Brown   }
29464c30e9fbSJed Brown   {
29476719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
29486719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
29499566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag));
29509566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display));
29519566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw));
29529566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour));
29539566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold));
295427b0f280SBarry Smith     if (flag_threshold) {
29559566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL));
29569566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL));
295727b0f280SBarry Smith     }
29586719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
29594c30e9fbSJed Brown       Mat            Bfd;
29604c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2961335efc43SPeter Brune       MatColoring    coloring;
29624c30e9fbSJed Brown       ISColoring     iscoloring;
29634c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
29644c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
29654c30e9fbSJed Brown       void           *funcctx;
29666719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
29674c30e9fbSJed Brown 
29689566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd));
29699566063dSJacob Faibussowitsch       PetscCall(MatColoringCreate(Bfd,&coloring));
29709566063dSJacob Faibussowitsch       PetscCall(MatColoringSetType(coloring,MATCOLORINGSL));
29719566063dSJacob Faibussowitsch       PetscCall(MatColoringSetFromOptions(coloring));
29729566063dSJacob Faibussowitsch       PetscCall(MatColoringApply(coloring,&iscoloring));
29739566063dSJacob Faibussowitsch       PetscCall(MatColoringDestroy(&coloring));
29749566063dSJacob Faibussowitsch       PetscCall(MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring));
29759566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
29769566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring));
29779566063dSJacob Faibussowitsch       PetscCall(ISColoringDestroy(&iscoloring));
29784c30e9fbSJed Brown 
29794c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
29809566063dSJacob Faibussowitsch       PetscCall(SNESGetFunction(snes,NULL,&func,&funcctx));
29819566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx));
29829566063dSJacob Faibussowitsch       PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix));
29839566063dSJacob Faibussowitsch       PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_"));
29849566063dSJacob Faibussowitsch       PetscCall(MatFDColoringSetFromOptions(matfdcoloring));
29859566063dSJacob Faibussowitsch       PetscCall(MatFDColoringApply(Bfd,matfdcoloring,X,snes));
29869566063dSJacob Faibussowitsch       PetscCall(MatFDColoringDestroy(&matfdcoloring));
29874c30e9fbSJed Brown 
29889566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout));
29894c30e9fbSJed Brown       if (flag_draw || flag_contour) {
29909566063dSJacob Faibussowitsch         PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw));
29919566063dSJacob Faibussowitsch         if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
29920298fd71SBarry Smith       } else vdraw = NULL;
29939566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n"));
29949566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(B,vstdout));
29959566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(B,vdraw));
29969566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n"));
29979566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(Bfd,vstdout));
29989566063dSJacob Faibussowitsch       if (vdraw) PetscCall(MatView(Bfd,vdraw));
29999566063dSJacob Faibussowitsch       PetscCall(MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN));
30009566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd,NORM_1,&norm1));
30019566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd,NORM_FROBENIUS,&norm2));
30029566063dSJacob Faibussowitsch       PetscCall(MatNorm(Bfd,NORM_MAX,&normmax));
30039566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax));
30049566063dSJacob Faibussowitsch       if (flag_display) PetscCall(MatView(Bfd,vstdout));
30054c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
30069566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR));
30079566063dSJacob Faibussowitsch         PetscCall(MatView(Bfd,vdraw));
30089566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(vdraw));
30094c30e9fbSJed Brown       }
30109566063dSJacob Faibussowitsch       if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw));
30116719d8e4SJed Brown 
30126719d8e4SJed Brown       if (flag_threshold) {
30136719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
30149566063dSJacob Faibussowitsch         PetscCall(MatGetBlockSize(B,&bs));
30159566063dSJacob Faibussowitsch         PetscCall(MatGetOwnershipRange(B,&rstart,&rend));
30166719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
30176719d8e4SJed Brown           const PetscScalar *ba,*ca;
30186719d8e4SJed Brown           const PetscInt    *bj,*cj;
30196719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
30206719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
30219566063dSJacob Faibussowitsch           PetscCall(MatGetRow(B,i,&bn,&bj,&ba));
30229566063dSJacob Faibussowitsch           PetscCall(MatGetRow(Bfd,i,&cn,&cj,&ca));
30235f80ce2aSJacob Faibussowitsch           PetscCheck(bn == cn,((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
30246719d8e4SJed Brown           for (j=0; j<bn; j++) {
30256719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
30266719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
30276719d8e4SJed Brown               maxentrycol = bj[j];
30286719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
30296719d8e4SJed Brown             }
30306719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
30316719d8e4SJed Brown               maxdiffcol = bj[j];
30326719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
30336719d8e4SJed Brown             }
30346719d8e4SJed Brown             if (rdiff > maxrdiff) {
30356719d8e4SJed Brown               maxrdiffcol = bj[j];
30366719d8e4SJed Brown               maxrdiff    = rdiff;
30376719d8e4SJed Brown             }
30386719d8e4SJed Brown           }
30396719d8e4SJed Brown           if (maxrdiff > 1) {
304063a3b9bcSJacob 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));
30416719d8e4SJed Brown             for (j=0; j<bn; j++) {
30426719d8e4SJed Brown               PetscReal rdiff;
30436719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
30446719d8e4SJed Brown               if (rdiff > 1) {
304563a3b9bcSJacob Faibussowitsch                 PetscCall(PetscViewerASCIIPrintf(vstdout," (%" PetscInt_FMT ",%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j])));
30466719d8e4SJed Brown               }
30476719d8e4SJed Brown             }
304863a3b9bcSJacob Faibussowitsch             PetscCall(PetscViewerASCIIPrintf(vstdout,"\n"));
30496719d8e4SJed Brown           }
30509566063dSJacob Faibussowitsch           PetscCall(MatRestoreRow(B,i,&bn,&bj,&ba));
30519566063dSJacob Faibussowitsch           PetscCall(MatRestoreRow(Bfd,i,&cn,&cj,&ca));
30526719d8e4SJed Brown         }
30536719d8e4SJed Brown       }
30549566063dSJacob Faibussowitsch       PetscCall(PetscViewerDestroy(&vdraw));
30559566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&Bfd));
30564c30e9fbSJed Brown     }
30574c30e9fbSJed Brown   }
30583a40ed3dSBarry Smith   PetscFunctionReturn(0);
30599b94acceSBarry Smith }
30609b94acceSBarry Smith 
3061bf388a1fSBarry Smith /*MC
3062411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
3063bf388a1fSBarry Smith 
3064bf388a1fSBarry Smith      Synopsis:
3065411c0326SBarry Smith      #include "petscsnes.h"
3066411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
3067bf388a1fSBarry Smith 
30681843f636SBarry Smith      Collective on snes
30691843f636SBarry Smith 
30701843f636SBarry Smith     Input Parameters:
30711843f636SBarry Smith +  x - input vector, the Jacobian is to be computed at this value
3072bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
3073bf388a1fSBarry Smith 
30741843f636SBarry Smith     Output Parameters:
30751843f636SBarry Smith +  Amat - the matrix that defines the (approximate) Jacobian
30761843f636SBarry Smith -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
30771843f636SBarry Smith 
3078878cb397SSatish Balay    Level: intermediate
3079878cb397SSatish Balay 
3080db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()`
3081bf388a1fSBarry Smith M*/
3082bf388a1fSBarry Smith 
30839b94acceSBarry Smith /*@C
30849b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
3085044dda88SLois Curfman McInnes    location to store the matrix.
30869b94acceSBarry Smith 
3087d083f849SBarry Smith    Logically Collective on SNES
3088c7afd0dbSLois Curfman McInnes 
30899b94acceSBarry Smith    Input Parameters:
3090c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3091e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
3092e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
3093411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
3094c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
30950298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
30969b94acceSBarry Smith 
30979b94acceSBarry Smith    Notes:
3098e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
309916913363SBarry Smith    each matrix.
310016913363SBarry Smith 
3101895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
3102895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
3103895c21f2SBarry Smith 
31048d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
3105a8a26c1eSJed Brown    must be a MatFDColoring.
3106a8a26c1eSJed Brown 
3107c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
3108c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
3109c3cc8fd1SJed Brown 
311036851e7fSLois Curfman McInnes    Level: beginner
311136851e7fSLois Curfman McInnes 
3112db781477SPatrick Sanan .seealso: `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`,
3113db781477SPatrick Sanan           `SNESSetPicard()`, `SNESJacobianFunction`
31149b94acceSBarry Smith @*/
3115d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
31169b94acceSBarry Smith {
31176cab3a1bSJed Brown   DM             dm;
31183a7fca6bSBarry Smith 
31193a40ed3dSBarry Smith   PetscFunctionBegin;
31200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3121e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
3122e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
3123e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
3124e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
31259566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
31269566063dSJacob Faibussowitsch   PetscCall(DMSNESSetJacobian(dm,J,ctx));
3127e5d3d808SBarry Smith   if (Amat) {
31289566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Amat));
31299566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&snes->jacobian));
3130f5af7f23SKarl Rupp 
3131e5d3d808SBarry Smith     snes->jacobian = Amat;
31323a7fca6bSBarry Smith   }
3133e5d3d808SBarry Smith   if (Pmat) {
31349566063dSJacob Faibussowitsch     PetscCall(PetscObjectReference((PetscObject)Pmat));
31359566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&snes->jacobian_pre));
3136f5af7f23SKarl Rupp 
3137e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
31383a7fca6bSBarry Smith   }
31393a40ed3dSBarry Smith   PetscFunctionReturn(0);
31409b94acceSBarry Smith }
314162fef451SLois Curfman McInnes 
3142c2aafc4cSSatish Balay /*@C
3143b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
3144b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
3145b4fd4287SBarry Smith 
3146c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
3147c7afd0dbSLois Curfman McInnes 
3148b4fd4287SBarry Smith    Input Parameter:
3149b4fd4287SBarry Smith .  snes - the nonlinear solver context
3150b4fd4287SBarry Smith 
3151b4fd4287SBarry Smith    Output Parameters:
3152e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
3153e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
3154411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
31550298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
3156fee21e36SBarry Smith 
315736851e7fSLois Curfman McInnes    Level: advanced
315836851e7fSLois Curfman McInnes 
3159db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()`
3160b4fd4287SBarry Smith @*/
3161d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
3162b4fd4287SBarry Smith {
31636cab3a1bSJed Brown   DM             dm;
3164942e3340SBarry Smith   DMSNES         sdm;
31656cab3a1bSJed Brown 
31663a40ed3dSBarry Smith   PetscFunctionBegin;
31670700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3168e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
3169e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
31709566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
31719566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
3172f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
31736cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
31743a40ed3dSBarry Smith   PetscFunctionReturn(0);
3175b4fd4287SBarry Smith }
3176b4fd4287SBarry Smith 
317758b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
317858b371f3SBarry Smith {
317958b371f3SBarry Smith   DM             dm;
318058b371f3SBarry Smith   DMSNES         sdm;
318158b371f3SBarry Smith 
318258b371f3SBarry Smith   PetscFunctionBegin;
31839566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
31849566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
318558b371f3SBarry Smith   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
318658b371f3SBarry Smith     DM        dm;
318758b371f3SBarry Smith     PetscBool isdense,ismf;
318858b371f3SBarry Smith 
31899566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
31909566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL));
31919566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL));
319258b371f3SBarry Smith     if (isdense) {
31939566063dSJacob Faibussowitsch       PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL));
319458b371f3SBarry Smith     } else if (!ismf) {
31959566063dSJacob Faibussowitsch       PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL));
319658b371f3SBarry Smith     }
319758b371f3SBarry Smith   }
319858b371f3SBarry Smith   PetscFunctionReturn(0);
319958b371f3SBarry Smith }
320058b371f3SBarry Smith 
32019b94acceSBarry Smith /*@
32029b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
3203272ac6f2SLois Curfman McInnes    of a nonlinear solver.
32049b94acceSBarry Smith 
3205fee21e36SBarry Smith    Collective on SNES
3206fee21e36SBarry Smith 
3207c7afd0dbSLois Curfman McInnes    Input Parameters:
320870e92668SMatthew Knepley .  snes - the SNES context
3209c7afd0dbSLois Curfman McInnes 
3210272ac6f2SLois Curfman McInnes    Notes:
3211272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
3212272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
3213272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
3214272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
3215272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
3216272ac6f2SLois Curfman McInnes 
321736851e7fSLois Curfman McInnes    Level: advanced
321836851e7fSLois Curfman McInnes 
3219db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()`, `SNESDestroy()`
32209b94acceSBarry Smith @*/
32217087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
32229b94acceSBarry Smith {
32236cab3a1bSJed Brown   DM             dm;
3224942e3340SBarry Smith   DMSNES         sdm;
3225c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
32266e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
32276b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
32286b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
32296e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
32306e2a1849SPeter Brune   Vec            f,fpc;
32316e2a1849SPeter Brune   void           *funcctx;
3232d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
32331eb13d49SPeter Brune   void           *jacctx,*appctx;
323432b97717SPeter Brune   Mat            j,jpre;
32353a40ed3dSBarry Smith 
32363a40ed3dSBarry Smith   PetscFunctionBegin;
32370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
32384dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
32399566063dSJacob Faibussowitsch   PetscCall(PetscLogEventBegin(SNES_Setup,snes,0,0,0));
32409b94acceSBarry Smith 
32417adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
32429566063dSJacob Faibussowitsch     PetscCall(SNESSetType(snes,SNESNEWTONLS));
324385385478SLisandro Dalcin   }
324485385478SLisandro Dalcin 
32459566063dSJacob Faibussowitsch   PetscCall(SNESGetFunction(snes,&snes->vec_func,NULL,NULL));
324658c9b817SLisandro Dalcin 
32479566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
32489566063dSJacob Faibussowitsch   PetscCall(DMGetDMSNES(dm,&sdm));
32495f80ce2aSJacob Faibussowitsch   PetscCheck(sdm->ops->computefunction,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
32509566063dSJacob Faibussowitsch   PetscCall(SNESSetDefaultComputeJacobian(snes));
325158b371f3SBarry Smith 
32526cab3a1bSJed Brown   if (!snes->vec_func) {
32539566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(dm,&snes->vec_func));
3254214df951SJed Brown   }
3255efd51863SBarry Smith 
325622d28d08SBarry Smith   if (!snes->ksp) {
32579566063dSJacob Faibussowitsch     PetscCall(SNESGetKSP(snes, &snes->ksp));
325822d28d08SBarry Smith   }
3259b710008aSBarry Smith 
3260d8d34be6SBarry Smith   if (snes->linesearch) {
32619566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes, &snes->linesearch));
32629566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction));
3263d8d34be6SBarry Smith   }
32649e764e56SPeter Brune 
3265b552625fSStefano Zampini   if (snes->npc && snes->npcside == PC_LEFT) {
3266172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
3267172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
3268172a4300SPeter Brune   }
3269d8f46077SPeter Brune 
3270efd4aadfSBarry Smith   if (snes->npc) {
32716e2a1849SPeter Brune     /* copy the DM over */
32729566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
32739566063dSJacob Faibussowitsch     PetscCall(SNESSetDM(snes->npc,dm));
32746e2a1849SPeter Brune 
32759566063dSJacob Faibussowitsch     PetscCall(SNESGetFunction(snes,&f,&func,&funcctx));
32769566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(f,&fpc));
32779566063dSJacob Faibussowitsch     PetscCall(SNESSetFunction(snes->npc,fpc,func,funcctx));
32789566063dSJacob Faibussowitsch     PetscCall(SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx));
32799566063dSJacob Faibussowitsch     PetscCall(SNESSetJacobian(snes->npc,j,jpre,jac,jacctx));
32809566063dSJacob Faibussowitsch     PetscCall(SNESGetApplicationContext(snes,&appctx));
32819566063dSJacob Faibussowitsch     PetscCall(SNESSetApplicationContext(snes->npc,appctx));
32829566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&fpc));
32836e2a1849SPeter Brune 
32846e2a1849SPeter Brune     /* copy the function pointers over */
32859566063dSJacob Faibussowitsch     PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc));
32866e2a1849SPeter Brune 
32876e2a1849SPeter Brune     /* default to 1 iteration */
32889566063dSJacob Faibussowitsch     PetscCall(SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs));
3289efd4aadfSBarry Smith     if (snes->npcside == PC_RIGHT) {
32909566063dSJacob Faibussowitsch       PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY));
3291a9936a0cSPeter Brune     } else {
32929566063dSJacob Faibussowitsch       PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_NONE));
3293a9936a0cSPeter Brune     }
32949566063dSJacob Faibussowitsch     PetscCall(SNESSetFromOptions(snes->npc));
32956e2a1849SPeter Brune 
32966e2a1849SPeter Brune     /* copy the line search context over */
3297d8d34be6SBarry Smith     if (snes->linesearch && snes->npc->linesearch) {
32989566063dSJacob Faibussowitsch       PetscCall(SNESGetLineSearch(snes,&linesearch));
32999566063dSJacob Faibussowitsch       PetscCall(SNESGetLineSearch(snes->npc,&pclinesearch));
33009566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx));
33019566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx));
33029566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx));
33039566063dSJacob Faibussowitsch       PetscCall(SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx));
33049566063dSJacob Faibussowitsch       PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch));
33056e2a1849SPeter Brune     }
3306d8d34be6SBarry Smith   }
330732b97717SPeter Brune   if (snes->mf) {
33089566063dSJacob Faibussowitsch     PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version));
330932b97717SPeter Brune   }
331032b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
33119566063dSJacob Faibussowitsch     PetscCall((*snes->ops->usercompute)(snes,(void**)&snes->user));
331232b97717SPeter Brune   }
33136e2a1849SPeter Brune 
331437ec4e1aSPeter Brune   snes->jac_iter = 0;
331537ec4e1aSPeter Brune   snes->pre_iter = 0;
331637ec4e1aSPeter Brune 
3317410397dcSLisandro Dalcin   if (snes->ops->setup) {
33189566063dSJacob Faibussowitsch     PetscCall((*snes->ops->setup)(snes));
3319410397dcSLisandro Dalcin   }
332058c9b817SLisandro Dalcin 
33219566063dSJacob Faibussowitsch   PetscCall(SNESSetDefaultComputeJacobian(snes));
332258b371f3SBarry Smith 
3323b552625fSStefano Zampini   if (snes->npc && snes->npcside == PC_LEFT) {
33246c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3325d8d34be6SBarry Smith       if (snes->linesearch) {
33269566063dSJacob Faibussowitsch         PetscCall(SNESGetLineSearch(snes,&linesearch));
33279566063dSJacob Faibussowitsch         PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC));
33286c67d002SPeter Brune       }
33296c67d002SPeter Brune     }
3330d8d34be6SBarry Smith   }
33319566063dSJacob Faibussowitsch   PetscCall(PetscLogEventEnd(SNES_Setup,snes,0,0,0));
33327aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
33333a40ed3dSBarry Smith   PetscFunctionReturn(0);
33349b94acceSBarry Smith }
33359b94acceSBarry Smith 
333637596af1SLisandro Dalcin /*@
333737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
333837596af1SLisandro Dalcin 
333937596af1SLisandro Dalcin    Collective on SNES
334037596af1SLisandro Dalcin 
334137596af1SLisandro Dalcin    Input Parameter:
334237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
334337596af1SLisandro Dalcin 
3344d25893d9SBarry Smith    Level: intermediate
3345d25893d9SBarry Smith 
334695452b02SPatrick Sanan    Notes:
334795452b02SPatrick Sanan     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
334837596af1SLisandro Dalcin 
3349db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESSolve()`
335037596af1SLisandro Dalcin @*/
335137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
335237596af1SLisandro Dalcin {
335337596af1SLisandro Dalcin   PetscFunctionBegin;
335437596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3355d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
33569566063dSJacob Faibussowitsch     PetscCall((*snes->ops->userdestroy)((void**)&snes->user));
33570298fd71SBarry Smith     snes->user = NULL;
3358d25893d9SBarry Smith   }
3359efd4aadfSBarry Smith   if (snes->npc) {
33609566063dSJacob Faibussowitsch     PetscCall(SNESReset(snes->npc));
33618a23116dSBarry Smith   }
33628a23116dSBarry Smith 
336337596af1SLisandro Dalcin   if (snes->ops->reset) {
33649566063dSJacob Faibussowitsch     PetscCall((*snes->ops->reset)(snes));
336537596af1SLisandro Dalcin   }
33669e764e56SPeter Brune   if (snes->ksp) {
33679566063dSJacob Faibussowitsch     PetscCall(KSPReset(snes->ksp));
33689e764e56SPeter Brune   }
33699e764e56SPeter Brune 
33709e764e56SPeter Brune   if (snes->linesearch) {
33719566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchReset(snes->linesearch));
33729e764e56SPeter Brune   }
33739e764e56SPeter Brune 
33749566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_rhs));
33759566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol));
33769566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol_update));
33779566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_func));
33789566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->jacobian));
33799566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->jacobian_pre));
33809566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&snes->picard));
33819566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(snes->nwork,&snes->work));
33829566063dSJacob Faibussowitsch   PetscCall(VecDestroyVecs(snes->nvwork,&snes->vwork));
3383f5af7f23SKarl Rupp 
338440fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
338540fdac6aSLawrence Mitchell 
338637596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
338737596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
338837596af1SLisandro Dalcin   PetscFunctionReturn(0);
338937596af1SLisandro Dalcin }
339037596af1SLisandro Dalcin 
339152baeb72SSatish Balay /*@
3392c4421ceaSFande Kong    SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object.
3393c4421ceaSFande Kong 
3394c4421ceaSFande Kong    Collective on SNES
3395c4421ceaSFande Kong 
3396c4421ceaSFande Kong    Input Parameter:
3397c4421ceaSFande Kong .  snes - iterative context obtained from SNESCreate()
3398c4421ceaSFande Kong 
3399c4421ceaSFande Kong    Level: intermediate
3400c4421ceaSFande Kong 
3401db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESReset()`
3402c4421ceaSFande Kong @*/
3403c4421ceaSFande Kong PetscErrorCode  SNESConvergedReasonViewCancel(SNES snes)
3404c4421ceaSFande Kong {
3405c4421ceaSFande Kong   PetscInt       i;
3406c4421ceaSFande Kong 
3407c4421ceaSFande Kong   PetscFunctionBegin;
3408c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3409c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews; i++) {
3410c4421ceaSFande Kong     if (snes->reasonviewdestroy[i]) {
34119566063dSJacob Faibussowitsch       PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]));
3412c4421ceaSFande Kong     }
3413c4421ceaSFande Kong   }
3414c4421ceaSFande Kong   snes->numberreasonviews = 0;
3415c4421ceaSFande Kong   PetscFunctionReturn(0);
3416c4421ceaSFande Kong }
3417c4421ceaSFande Kong 
34181fb7b255SJunchao Zhang /*@C
34199b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
34209b94acceSBarry Smith    with SNESCreate().
34219b94acceSBarry Smith 
3422c7afd0dbSLois Curfman McInnes    Collective on SNES
3423c7afd0dbSLois Curfman McInnes 
34249b94acceSBarry Smith    Input Parameter:
34259b94acceSBarry Smith .  snes - the SNES context
34269b94acceSBarry Smith 
342736851e7fSLois Curfman McInnes    Level: beginner
342836851e7fSLois Curfman McInnes 
3429db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()`
34309b94acceSBarry Smith @*/
34316bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
34329b94acceSBarry Smith {
34333a40ed3dSBarry Smith   PetscFunctionBegin;
34346bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
34356bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
34369e5d0892SLisandro Dalcin   if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);}
3437d4bb536fSBarry Smith 
34389566063dSJacob Faibussowitsch   PetscCall(SNESReset((*snes)));
34399566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&(*snes)->npc));
34406b8b9a38SLisandro Dalcin 
3441e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
34429566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes));
34439566063dSJacob Faibussowitsch   if ((*snes)->ops->destroy) PetscCall((*((*snes))->ops->destroy)((*snes)));
34446d4c513bSLisandro Dalcin 
34459566063dSJacob Faibussowitsch   if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes));
34469566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&(*snes)->dm));
34479566063dSJacob Faibussowitsch   PetscCall(KSPDestroy(&(*snes)->ksp));
34489566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch));
34496b8b9a38SLisandro Dalcin 
34509566063dSJacob Faibussowitsch   PetscCall(PetscFree((*snes)->kspconvctx));
34516bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
34529566063dSJacob Faibussowitsch     PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP));
34536b8b9a38SLisandro Dalcin   }
3454071fcb05SBarry Smith   if ((*snes)->conv_hist_alloc) {
34559566063dSJacob Faibussowitsch     PetscCall(PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its));
345658c9b817SLisandro Dalcin   }
34579566063dSJacob Faibussowitsch   PetscCall(SNESMonitorCancel((*snes)));
34589566063dSJacob Faibussowitsch   PetscCall(SNESConvergedReasonViewCancel((*snes)));
34599566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(snes));
34603a40ed3dSBarry Smith   PetscFunctionReturn(0);
34619b94acceSBarry Smith }
34629b94acceSBarry Smith 
34639b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
34649b94acceSBarry Smith 
3465a8054027SBarry Smith /*@
3466a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3467a8054027SBarry Smith 
34683f9fe445SBarry Smith    Logically Collective on SNES
3469a8054027SBarry Smith 
3470a8054027SBarry Smith    Input Parameters:
3471a8054027SBarry Smith +  snes - the SNES context
3472d8e291bfSBarry Smith -  lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
34733b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3474a8054027SBarry Smith 
3475a8054027SBarry Smith    Options Database Keys:
34763d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34773d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34783d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34793d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3480a8054027SBarry Smith 
3481a8054027SBarry Smith    Notes:
3482a8054027SBarry Smith    The default is 1
34833d5a8a6aSBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called
3484d8e291bfSBarry Smith 
3485d8e291bfSBarry Smith    SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves.
3486a8054027SBarry Smith 
3487a8054027SBarry Smith    Level: intermediate
3488a8054027SBarry Smith 
3489db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`,
3490db781477SPatrick Sanan           `SNESSetLagJacobianPersists()`
3491a8054027SBarry Smith 
3492a8054027SBarry Smith @*/
34937087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
3494a8054027SBarry Smith {
3495a8054027SBarry Smith   PetscFunctionBegin;
34960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34975f80ce2aSJacob Faibussowitsch   PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
34985f80ce2aSJacob Faibussowitsch   PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3499c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3500a8054027SBarry Smith   snes->lagpreconditioner = lag;
3501a8054027SBarry Smith   PetscFunctionReturn(0);
3502a8054027SBarry Smith }
3503a8054027SBarry Smith 
3504efd51863SBarry Smith /*@
3505efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
3506efd51863SBarry Smith 
3507efd51863SBarry Smith    Logically Collective on SNES
3508efd51863SBarry Smith 
3509efd51863SBarry Smith    Input Parameters:
3510efd51863SBarry Smith +  snes - the SNES context
3511efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
3512efd51863SBarry Smith 
3513efd51863SBarry Smith    Options Database Keys:
351467b8a455SSatish Balay .    -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess
3515efd51863SBarry Smith 
3516efd51863SBarry Smith    Level: intermediate
3517efd51863SBarry Smith 
3518c0df2a02SJed Brown    Notes:
3519c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3520c0df2a02SJed Brown 
3521db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()`
3522efd51863SBarry Smith 
3523efd51863SBarry Smith @*/
3524efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
3525efd51863SBarry Smith {
3526efd51863SBarry Smith   PetscFunctionBegin;
3527efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3528efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
3529efd51863SBarry Smith   snes->gridsequence = steps;
3530efd51863SBarry Smith   PetscFunctionReturn(0);
3531efd51863SBarry Smith }
3532efd51863SBarry Smith 
3533fa19ca70SBarry Smith /*@
3534fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
3535fa19ca70SBarry Smith 
3536fa19ca70SBarry Smith    Logically Collective on SNES
3537fa19ca70SBarry Smith 
3538fa19ca70SBarry Smith    Input Parameter:
3539fa19ca70SBarry Smith .  snes - the SNES context
3540fa19ca70SBarry Smith 
3541fa19ca70SBarry Smith    Output Parameter:
3542fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
3543fa19ca70SBarry Smith 
3544fa19ca70SBarry Smith    Options Database Keys:
354567b8a455SSatish Balay .    -snes_grid_sequence <steps> - set number of refinements
3546fa19ca70SBarry Smith 
3547fa19ca70SBarry Smith    Level: intermediate
3548fa19ca70SBarry Smith 
3549fa19ca70SBarry Smith    Notes:
3550fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3551fa19ca70SBarry Smith 
3552db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()`
3553fa19ca70SBarry Smith 
3554fa19ca70SBarry Smith @*/
3555fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3556fa19ca70SBarry Smith {
3557fa19ca70SBarry Smith   PetscFunctionBegin;
3558fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3559fa19ca70SBarry Smith   *steps = snes->gridsequence;
3560fa19ca70SBarry Smith   PetscFunctionReturn(0);
3561fa19ca70SBarry Smith }
3562fa19ca70SBarry Smith 
3563a8054027SBarry Smith /*@
3564a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3565a8054027SBarry Smith 
35663f9fe445SBarry Smith    Not Collective
3567a8054027SBarry Smith 
3568a8054027SBarry Smith    Input Parameter:
3569a8054027SBarry Smith .  snes - the SNES context
3570a8054027SBarry Smith 
3571a8054027SBarry Smith    Output Parameter:
3572a8054027SBarry 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
35733b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3574a8054027SBarry Smith 
3575a8054027SBarry Smith    Options Database Keys:
35763d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35773d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35783d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35793d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3580a8054027SBarry Smith 
3581a8054027SBarry Smith    Notes:
3582a8054027SBarry Smith    The default is 1
3583a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3584a8054027SBarry Smith 
3585a8054027SBarry Smith    Level: intermediate
3586a8054027SBarry Smith 
3587db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3588a8054027SBarry Smith 
3589a8054027SBarry Smith @*/
35907087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3591a8054027SBarry Smith {
3592a8054027SBarry Smith   PetscFunctionBegin;
35930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3594a8054027SBarry Smith   *lag = snes->lagpreconditioner;
3595a8054027SBarry Smith   PetscFunctionReturn(0);
3596a8054027SBarry Smith }
3597a8054027SBarry Smith 
3598e35cf81dSBarry Smith /*@
3599e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3600e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3601e35cf81dSBarry Smith 
36023f9fe445SBarry Smith    Logically Collective on SNES
3603e35cf81dSBarry Smith 
3604e35cf81dSBarry Smith    Input Parameters:
3605e35cf81dSBarry Smith +  snes - the SNES context
3606e35cf81dSBarry 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
3607fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3608e35cf81dSBarry Smith 
3609e35cf81dSBarry Smith    Options Database Keys:
36103d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
36113d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
36123d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
36133d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag.
3614e35cf81dSBarry Smith 
3615e35cf81dSBarry Smith    Notes:
3616e35cf81dSBarry Smith    The default is 1
3617e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3618fe3ffe1eSBarry 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
3619fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3620e35cf81dSBarry Smith 
3621e35cf81dSBarry Smith    Level: intermediate
3622e35cf81dSBarry Smith 
3623db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3624e35cf81dSBarry Smith 
3625e35cf81dSBarry Smith @*/
36267087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3627e35cf81dSBarry Smith {
3628e35cf81dSBarry Smith   PetscFunctionBegin;
36290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36305f80ce2aSJacob Faibussowitsch   PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
36315f80ce2aSJacob Faibussowitsch   PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3632c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3633e35cf81dSBarry Smith   snes->lagjacobian = lag;
3634e35cf81dSBarry Smith   PetscFunctionReturn(0);
3635e35cf81dSBarry Smith }
3636e35cf81dSBarry Smith 
3637e35cf81dSBarry Smith /*@
3638e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3639e35cf81dSBarry Smith 
36403f9fe445SBarry Smith    Not Collective
3641e35cf81dSBarry Smith 
3642e35cf81dSBarry Smith    Input Parameter:
3643e35cf81dSBarry Smith .  snes - the SNES context
3644e35cf81dSBarry Smith 
3645e35cf81dSBarry Smith    Output Parameter:
3646e35cf81dSBarry 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
3647e35cf81dSBarry Smith          the Jacobian is built etc.
3648e35cf81dSBarry Smith 
3649e35cf81dSBarry Smith    Notes:
3650e35cf81dSBarry Smith    The default is 1
36513d5a8a6aSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called.
3652e35cf81dSBarry Smith 
3653e35cf81dSBarry Smith    Level: intermediate
3654e35cf81dSBarry Smith 
3655db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()`
3656e35cf81dSBarry Smith 
3657e35cf81dSBarry Smith @*/
36587087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3659e35cf81dSBarry Smith {
3660e35cf81dSBarry Smith   PetscFunctionBegin;
36610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3662e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3663e35cf81dSBarry Smith   PetscFunctionReturn(0);
3664e35cf81dSBarry Smith }
3665e35cf81dSBarry Smith 
366637ec4e1aSPeter Brune /*@
366737ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
366837ec4e1aSPeter Brune 
366937ec4e1aSPeter Brune    Logically collective on SNES
367037ec4e1aSPeter Brune 
3671d8d19677SJose E. Roman    Input Parameters:
367237ec4e1aSPeter Brune +  snes - the SNES context
36739d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
367437ec4e1aSPeter Brune 
367537ec4e1aSPeter Brune    Options Database Keys:
36763d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
36773d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
36783d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
36793d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
36803d5a8a6aSBarry Smith 
368195452b02SPatrick Sanan    Notes:
368295452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
368337ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
368437ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
368537ec4e1aSPeter Brune 
368637ec4e1aSPeter Brune    Level: developer
368737ec4e1aSPeter Brune 
3688db781477SPatrick Sanan .seealso: `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()`
368937ec4e1aSPeter Brune 
369037ec4e1aSPeter Brune @*/
369137ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
369237ec4e1aSPeter Brune {
369337ec4e1aSPeter Brune   PetscFunctionBegin;
369437ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
369537ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
369637ec4e1aSPeter Brune   snes->lagjac_persist = flg;
369737ec4e1aSPeter Brune   PetscFunctionReturn(0);
369837ec4e1aSPeter Brune }
369937ec4e1aSPeter Brune 
370037ec4e1aSPeter Brune /*@
3701d8e291bfSBarry Smith    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
370237ec4e1aSPeter Brune 
370337ec4e1aSPeter Brune    Logically Collective on SNES
370437ec4e1aSPeter Brune 
3705d8d19677SJose E. Roman    Input Parameters:
370637ec4e1aSPeter Brune +  snes - the SNES context
37079d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
370837ec4e1aSPeter Brune 
370937ec4e1aSPeter Brune    Options Database Keys:
37103d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
37113d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
37123d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
37133d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
371437ec4e1aSPeter Brune 
371595452b02SPatrick Sanan    Notes:
371695452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
371737ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
371837ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
371937ec4e1aSPeter Brune 
372037ec4e1aSPeter Brune    Level: developer
372137ec4e1aSPeter Brune 
3722db781477SPatrick Sanan .seealso: `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()`
372337ec4e1aSPeter Brune 
372437ec4e1aSPeter Brune @*/
372537ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
372637ec4e1aSPeter Brune {
372737ec4e1aSPeter Brune   PetscFunctionBegin;
372837ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
372937ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
373037ec4e1aSPeter Brune   snes->lagpre_persist = flg;
373137ec4e1aSPeter Brune   PetscFunctionReturn(0);
373237ec4e1aSPeter Brune }
373337ec4e1aSPeter Brune 
37349b94acceSBarry Smith /*@
3735be5caee7SBarry Smith    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm
3736be5caee7SBarry Smith 
3737be5caee7SBarry Smith    Logically Collective on SNES
3738be5caee7SBarry Smith 
3739be5caee7SBarry Smith    Input Parameters:
3740be5caee7SBarry Smith +  snes - the SNES context
3741be5caee7SBarry Smith -  force - PETSC_TRUE require at least one iteration
3742be5caee7SBarry Smith 
3743be5caee7SBarry Smith    Options Database Keys:
3744be5caee7SBarry Smith .    -snes_force_iteration <force> - Sets forcing an iteration
3745be5caee7SBarry Smith 
3746be5caee7SBarry Smith    Notes:
3747be5caee7SBarry Smith    This is used sometimes with TS to prevent TS from detecting a false steady state solution
3748be5caee7SBarry Smith 
3749be5caee7SBarry Smith    Level: intermediate
3750be5caee7SBarry Smith 
3751db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
3752be5caee7SBarry Smith @*/
3753be5caee7SBarry Smith PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
3754be5caee7SBarry Smith {
3755be5caee7SBarry Smith   PetscFunctionBegin;
3756be5caee7SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3757be5caee7SBarry Smith   snes->forceiteration = force;
3758be5caee7SBarry Smith   PetscFunctionReturn(0);
3759be5caee7SBarry Smith }
3760be5caee7SBarry Smith 
376185216dc7SFande Kong /*@
376285216dc7SFande Kong    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm
376385216dc7SFande Kong 
376485216dc7SFande Kong    Logically Collective on SNES
376585216dc7SFande Kong 
376685216dc7SFande Kong    Input Parameters:
376785216dc7SFande Kong .  snes - the SNES context
376885216dc7SFande Kong 
376985216dc7SFande Kong    Output Parameter:
377085216dc7SFande Kong .  force - PETSC_TRUE requires at least one iteration.
377185216dc7SFande Kong 
377206dd6b0eSSatish Balay    Level: intermediate
377306dd6b0eSSatish Balay 
3774db781477SPatrick Sanan .seealso: `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`
377585216dc7SFande Kong @*/
377685216dc7SFande Kong PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
377785216dc7SFande Kong {
377885216dc7SFande Kong   PetscFunctionBegin;
377985216dc7SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
378085216dc7SFande Kong   *force = snes->forceiteration;
378185216dc7SFande Kong   PetscFunctionReturn(0);
378285216dc7SFande Kong }
3783be5caee7SBarry Smith 
3784be5caee7SBarry Smith /*@
3785d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
37869b94acceSBarry Smith 
37873f9fe445SBarry Smith    Logically Collective on SNES
3788c7afd0dbSLois Curfman McInnes 
37899b94acceSBarry Smith    Input Parameters:
3790c7afd0dbSLois Curfman McInnes +  snes - the SNES context
379170441072SBarry Smith .  abstol - absolute convergence tolerance
379233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
37935358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
379433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3795e71169deSBarry Smith -  maxf - maximum number of function evaluations (-1 indicates no limit)
3796fee21e36SBarry Smith 
379733174efeSLois Curfman McInnes    Options Database Keys:
379870441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3799c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3800c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3801c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3802c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
38039b94acceSBarry Smith 
3804d7a720efSLois Curfman McInnes    Notes:
38059b94acceSBarry Smith    The default maximum number of iterations is 50.
38069b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
38079b94acceSBarry Smith 
380836851e7fSLois Curfman McInnes    Level: intermediate
380936851e7fSLois Curfman McInnes 
3810db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()`
38119b94acceSBarry Smith @*/
38127087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
38139b94acceSBarry Smith {
38143a40ed3dSBarry Smith   PetscFunctionBegin;
38150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3816c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3817c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3818c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3819c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3820c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3821c5eb9154SBarry Smith 
3822ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
38235f80ce2aSJacob Faibussowitsch     PetscCheck(abstol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3824ab54825eSJed Brown     snes->abstol = abstol;
3825ab54825eSJed Brown   }
3826ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
38275f80ce2aSJacob 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);
3828ab54825eSJed Brown     snes->rtol = rtol;
3829ab54825eSJed Brown   }
3830ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
38315f80ce2aSJacob Faibussowitsch     PetscCheck(stol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3832c60f73f4SPeter Brune     snes->stol = stol;
3833ab54825eSJed Brown   }
3834ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
383563a3b9bcSJacob Faibussowitsch     PetscCheck(maxit >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",maxit);
3836ab54825eSJed Brown     snes->max_its = maxit;
3837ab54825eSJed Brown   }
3838ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
383963a3b9bcSJacob Faibussowitsch     PetscCheck(maxf >= -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative",maxf);
3840ab54825eSJed Brown     snes->max_funcs = maxf;
3841ab54825eSJed Brown   }
384288976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
38433a40ed3dSBarry Smith   PetscFunctionReturn(0);
38449b94acceSBarry Smith }
38459b94acceSBarry Smith 
3846e4d06f11SPatrick Farrell /*@
3847e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3848e4d06f11SPatrick Farrell 
3849e4d06f11SPatrick Farrell    Logically Collective on SNES
3850e4d06f11SPatrick Farrell 
3851e4d06f11SPatrick Farrell    Input Parameters:
3852e4d06f11SPatrick Farrell +  snes - the SNES context
3853e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3854e4d06f11SPatrick Farrell 
3855e4d06f11SPatrick Farrell    Options Database Keys:
3856a2b725a8SWilliam Gropp .    -snes_divergence_tolerance <divtol> - Sets divtol
3857e4d06f11SPatrick Farrell 
3858e4d06f11SPatrick Farrell    Notes:
3859e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3860e4d06f11SPatrick Farrell 
3861e4d06f11SPatrick Farrell    Level: intermediate
3862e4d06f11SPatrick Farrell 
3863db781477SPatrick Sanan .seealso: `SNESSetTolerances()`, `SNESGetDivergenceTolerance`
3864e4d06f11SPatrick Farrell @*/
3865e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3866e4d06f11SPatrick Farrell {
3867e4d06f11SPatrick Farrell   PetscFunctionBegin;
3868e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3869e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3870e4d06f11SPatrick Farrell 
3871e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3872e4d06f11SPatrick Farrell     snes->divtol = divtol;
3873e4d06f11SPatrick Farrell   }
3874e4d06f11SPatrick Farrell   else {
3875e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3876e4d06f11SPatrick Farrell   }
3877e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3878e4d06f11SPatrick Farrell }
3879e4d06f11SPatrick Farrell 
38809b94acceSBarry Smith /*@
388133174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
388233174efeSLois Curfman McInnes 
3883c7afd0dbSLois Curfman McInnes    Not Collective
3884c7afd0dbSLois Curfman McInnes 
388533174efeSLois Curfman McInnes    Input Parameters:
3886c7afd0dbSLois Curfman McInnes +  snes - the SNES context
388785385478SLisandro Dalcin .  atol - absolute convergence tolerance
388833174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
388933174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
389033174efeSLois Curfman McInnes            of the change in the solution between steps
389133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3892c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3893fee21e36SBarry Smith 
389433174efeSLois Curfman McInnes    Notes:
38950298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
389633174efeSLois Curfman McInnes 
389736851e7fSLois Curfman McInnes    Level: intermediate
389836851e7fSLois Curfman McInnes 
3899db781477SPatrick Sanan .seealso: `SNESSetTolerances()`
390033174efeSLois Curfman McInnes @*/
39017087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
390233174efeSLois Curfman McInnes {
39033a40ed3dSBarry Smith   PetscFunctionBegin;
39040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
390585385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
390633174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3907c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
390833174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
390933174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
39103a40ed3dSBarry Smith   PetscFunctionReturn(0);
391133174efeSLois Curfman McInnes }
391233174efeSLois Curfman McInnes 
3913e4d06f11SPatrick Farrell /*@
3914e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3915e4d06f11SPatrick Farrell 
3916e4d06f11SPatrick Farrell    Not Collective
3917e4d06f11SPatrick Farrell 
3918e4d06f11SPatrick Farrell    Input Parameters:
3919e4d06f11SPatrick Farrell +  snes - the SNES context
3920e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3921e4d06f11SPatrick Farrell 
3922e4d06f11SPatrick Farrell    Level: intermediate
3923e4d06f11SPatrick Farrell 
3924db781477SPatrick Sanan .seealso: `SNESSetDivergenceTolerance()`
3925e4d06f11SPatrick Farrell @*/
3926e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3927e4d06f11SPatrick Farrell {
3928e4d06f11SPatrick Farrell   PetscFunctionBegin;
3929e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3930e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3931e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3932e4d06f11SPatrick Farrell }
3933e4d06f11SPatrick Farrell 
393433174efeSLois Curfman McInnes /*@
39359b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
39369b94acceSBarry Smith 
39373f9fe445SBarry Smith    Logically Collective on SNES
3938fee21e36SBarry Smith 
3939c7afd0dbSLois Curfman McInnes    Input Parameters:
3940c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3941c7afd0dbSLois Curfman McInnes -  tol - tolerance
3942c7afd0dbSLois Curfman McInnes 
39439b94acceSBarry Smith    Options Database Key:
3944c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
39459b94acceSBarry Smith 
394636851e7fSLois Curfman McInnes    Level: intermediate
394736851e7fSLois Curfman McInnes 
3948db781477SPatrick Sanan .seealso: `SNESSetTolerances()`
39499b94acceSBarry Smith @*/
39507087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
39519b94acceSBarry Smith {
39523a40ed3dSBarry Smith   PetscFunctionBegin;
39530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3954c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
39559b94acceSBarry Smith   snes->deltatol = tol;
39563a40ed3dSBarry Smith   PetscFunctionReturn(0);
39579b94acceSBarry Smith }
39589b94acceSBarry Smith 
39596ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
39606ba87a44SLisandro Dalcin 
39617087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3962b271bb04SBarry Smith {
3963b271bb04SBarry Smith   PetscDrawLG      lg;
3964b271bb04SBarry Smith   PetscReal        x,y,per;
3965b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3966b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3967b271bb04SBarry Smith   PetscDraw        draw;
3968b271bb04SBarry Smith 
3969459f5d12SBarry Smith   PetscFunctionBegin;
39704d4332d5SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
39719566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v,0,&lg));
39729566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
39739566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg,&draw));
39749566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw,"Residual norm"));
3975b271bb04SBarry Smith   x    = (PetscReal)n;
397677b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
397794c9c6d3SKarl Rupp   else y = -15.0;
39789566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
39796934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
39809566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
39819566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3982b271bb04SBarry Smith   }
3983b271bb04SBarry Smith 
39849566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v,1,&lg));
39859566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
39869566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg,&draw));
39879566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw,"% elemts > .2*max elemt"));
39889566063dSJacob Faibussowitsch   PetscCall(SNESMonitorRange_Private(snes,n,&per));
3989b271bb04SBarry Smith   x    = (PetscReal)n;
3990b271bb04SBarry Smith   y    = 100.0*per;
39919566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
39926934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
39939566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
39949566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
3995b271bb04SBarry Smith   }
3996b271bb04SBarry Smith 
39979566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v,2,&lg));
39989566063dSJacob Faibussowitsch   if (!n) {prev = rnorm;PetscCall(PetscDrawLGReset(lg));}
39999566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg,&draw));
40009566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm"));
4001b271bb04SBarry Smith   x    = (PetscReal)n;
4002b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
40039566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
40046934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
40059566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
40069566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
4007b271bb04SBarry Smith   }
4008b271bb04SBarry Smith 
40099566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDrawLG(v,3,&lg));
40109566063dSJacob Faibussowitsch   if (!n) PetscCall(PetscDrawLGReset(lg));
40119566063dSJacob Faibussowitsch   PetscCall(PetscDrawLGGetDraw(lg,&draw));
40129566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)"));
4013b271bb04SBarry Smith   x    = (PetscReal)n;
4014b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
4015b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
40169566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGAddPoint(lg,&x,&y));
4017b271bb04SBarry Smith   }
40186934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
40199566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGDraw(lg));
40209566063dSJacob Faibussowitsch     PetscCall(PetscDrawLGSave(lg));
4021b271bb04SBarry Smith   }
4022b271bb04SBarry Smith   prev = rnorm;
4023b271bb04SBarry Smith   PetscFunctionReturn(0);
4024b271bb04SBarry Smith }
4025b271bb04SBarry Smith 
4026228d79bcSJed Brown /*@
4027228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
4028228d79bcSJed Brown 
4029228d79bcSJed Brown    Collective on SNES
4030228d79bcSJed Brown 
4031228d79bcSJed Brown    Input Parameters:
4032228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
4033228d79bcSJed Brown .  iter - iteration number
4034228d79bcSJed Brown -  rnorm - relative norm of the residual
4035228d79bcSJed Brown 
4036228d79bcSJed Brown    Notes:
4037228d79bcSJed Brown    This routine is called by the SNES implementations.
4038228d79bcSJed Brown    It does not typically need to be called by the user.
4039228d79bcSJed Brown 
4040228d79bcSJed Brown    Level: developer
4041228d79bcSJed Brown 
4042db781477SPatrick Sanan .seealso: `SNESMonitorSet()`
4043228d79bcSJed Brown @*/
40447a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
40457a03ce2fSLisandro Dalcin {
40467a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
40477a03ce2fSLisandro Dalcin 
40487a03ce2fSLisandro Dalcin   PetscFunctionBegin;
40499566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(snes->vec_sol));
40507a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
40519566063dSJacob Faibussowitsch     PetscCall((*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]));
40527a03ce2fSLisandro Dalcin   }
40539566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(snes->vec_sol));
40547a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
40557a03ce2fSLisandro Dalcin }
40567a03ce2fSLisandro Dalcin 
40579b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
40589b94acceSBarry Smith 
4059bf388a1fSBarry Smith /*MC
4060bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
4061bf388a1fSBarry Smith 
4062bf388a1fSBarry Smith      Synopsis:
4063aaa7dc30SBarry Smith      #include <petscsnes.h>
4064bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
4065bf388a1fSBarry Smith 
40661843f636SBarry Smith      Collective on snes
40671843f636SBarry Smith 
40681843f636SBarry Smith     Input Parameters:
4069bf388a1fSBarry Smith +    snes - the SNES context
4070bf388a1fSBarry Smith .    its - iteration number
4071bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
4072bf388a1fSBarry Smith -    mctx - [optional] monitoring context
4073bf388a1fSBarry Smith 
4074878cb397SSatish Balay    Level: advanced
4075878cb397SSatish Balay 
4076db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorGet()`
4077bf388a1fSBarry Smith M*/
4078bf388a1fSBarry Smith 
40799b94acceSBarry Smith /*@C
4080a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
40819b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
40829b94acceSBarry Smith    progress.
40839b94acceSBarry Smith 
40843f9fe445SBarry Smith    Logically Collective on SNES
4085fee21e36SBarry Smith 
4086c7afd0dbSLois Curfman McInnes    Input Parameters:
4087c7afd0dbSLois Curfman McInnes +  snes - the SNES context
40886e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
4089b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
40900298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
4091b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
40920298fd71SBarry Smith           (may be NULL)
40939b94acceSBarry Smith 
40949665c990SLois Curfman McInnes    Options Database Keys:
4095a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
4096798534f6SMatthew G. Knepley .    -snes_monitor draw::draw_lg - sets line graph monitor,
4097cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
4098c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
4099a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
4100c7afd0dbSLois Curfman McInnes                             does not cancel those set via
4101c7afd0dbSLois Curfman McInnes                             the options database.
41029665c990SLois Curfman McInnes 
4103639f9d9dSBarry Smith    Notes:
41046bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
4105a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
41066bc08f3fSLois Curfman McInnes    order in which they were set.
4107639f9d9dSBarry Smith 
410895452b02SPatrick Sanan    Fortran Notes:
410995452b02SPatrick Sanan     Only a single monitor function can be set for each SNES object
4110025f1a04SBarry Smith 
411136851e7fSLois Curfman McInnes    Level: intermediate
411236851e7fSLois Curfman McInnes 
4113db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction`
41149b94acceSBarry Smith @*/
41156e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
41169b94acceSBarry Smith {
4117b90d0a6eSBarry Smith   PetscInt       i;
411878064530SBarry Smith   PetscBool      identical;
4119b90d0a6eSBarry Smith 
41203a40ed3dSBarry Smith   PetscFunctionBegin;
41210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4122b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
41239566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical));
412478064530SBarry Smith     if (identical) PetscFunctionReturn(0);
4125649052a6SBarry Smith   }
41265f80ce2aSJacob Faibussowitsch   PetscCheck(snes->numbermonitors < MAXSNESMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
41276e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
4128b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
4129639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
41303a40ed3dSBarry Smith   PetscFunctionReturn(0);
41319b94acceSBarry Smith }
41329b94acceSBarry Smith 
4133a278d85bSSatish Balay /*@
4134a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
41355cd90555SBarry Smith 
41363f9fe445SBarry Smith    Logically Collective on SNES
4137c7afd0dbSLois Curfman McInnes 
41385cd90555SBarry Smith    Input Parameters:
41395cd90555SBarry Smith .  snes - the SNES context
41405cd90555SBarry Smith 
41411a480d89SAdministrator    Options Database Key:
4142a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
4143a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
4144c7afd0dbSLois Curfman McInnes     set via the options database
41455cd90555SBarry Smith 
41465cd90555SBarry Smith    Notes:
41475cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
41485cd90555SBarry Smith 
414936851e7fSLois Curfman McInnes    Level: intermediate
415036851e7fSLois Curfman McInnes 
4151db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorSet()`
41525cd90555SBarry Smith @*/
41537087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
41545cd90555SBarry Smith {
4155d952e501SBarry Smith   PetscInt       i;
4156d952e501SBarry Smith 
41575cd90555SBarry Smith   PetscFunctionBegin;
41580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4159d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
4160d952e501SBarry Smith     if (snes->monitordestroy[i]) {
41619566063dSJacob Faibussowitsch       PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i]));
4162d952e501SBarry Smith     }
4163d952e501SBarry Smith   }
41645cd90555SBarry Smith   snes->numbermonitors = 0;
41655cd90555SBarry Smith   PetscFunctionReturn(0);
41665cd90555SBarry Smith }
41675cd90555SBarry Smith 
4168bf388a1fSBarry Smith /*MC
4169bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4170bf388a1fSBarry Smith 
4171bf388a1fSBarry Smith      Synopsis:
4172aaa7dc30SBarry Smith      #include <petscsnes.h>
4173bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
4174bf388a1fSBarry Smith 
41751843f636SBarry Smith      Collective on snes
41761843f636SBarry Smith 
41771843f636SBarry Smith     Input Parameters:
4178bf388a1fSBarry Smith +    snes - the SNES context
4179bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
4180bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
4181bf388a1fSBarry Smith .    gnorm - 2-norm of current step
41821843f636SBarry Smith .    f - 2-norm of function
41831843f636SBarry Smith -    cctx - [optional] convergence context
41841843f636SBarry Smith 
41851843f636SBarry Smith     Output Parameter:
41861843f636SBarry Smith .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4187bf388a1fSBarry Smith 
4188878cb397SSatish Balay    Level: intermediate
4189bf388a1fSBarry Smith 
4190db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()`
4191bf388a1fSBarry Smith M*/
4192bf388a1fSBarry Smith 
41939b94acceSBarry Smith /*@C
41949b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
41959b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
41969b94acceSBarry Smith 
41973f9fe445SBarry Smith    Logically Collective on SNES
4198fee21e36SBarry Smith 
4199c7afd0dbSLois Curfman McInnes    Input Parameters:
4200c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4201bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
42020298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
4203cf90aa19SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran)
42049b94acceSBarry Smith 
420536851e7fSLois Curfman McInnes    Level: advanced
420636851e7fSLois Curfman McInnes 
4207db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction`
42089b94acceSBarry Smith @*/
4209bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
42109b94acceSBarry Smith {
42113a40ed3dSBarry Smith   PetscFunctionBegin;
42120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4213e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
42147f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
42159566063dSJacob Faibussowitsch     PetscCall((*snes->ops->convergeddestroy)(snes->cnvP));
42167f7931b9SBarry Smith   }
4217bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
42187f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
421985385478SLisandro Dalcin   snes->cnvP                  = cctx;
42203a40ed3dSBarry Smith   PetscFunctionReturn(0);
42219b94acceSBarry Smith }
42229b94acceSBarry Smith 
422352baeb72SSatish Balay /*@
4224184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
4225184914b5SBarry Smith 
4226184914b5SBarry Smith    Not Collective
4227184914b5SBarry Smith 
4228184914b5SBarry Smith    Input Parameter:
4229184914b5SBarry Smith .  snes - the SNES context
4230184914b5SBarry Smith 
4231184914b5SBarry Smith    Output Parameter:
42324d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
4233184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
4234184914b5SBarry Smith 
42356a4d7782SBarry Smith    Options Database:
42366a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
42376a4d7782SBarry Smith 
4238184914b5SBarry Smith    Level: intermediate
4239184914b5SBarry Smith 
424095452b02SPatrick Sanan    Notes:
424195452b02SPatrick Sanan     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
4242184914b5SBarry Smith 
4243db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`
4244184914b5SBarry Smith @*/
42457087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
4246184914b5SBarry Smith {
4247184914b5SBarry Smith   PetscFunctionBegin;
42480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42494482741eSBarry Smith   PetscValidPointer(reason,2);
4250184914b5SBarry Smith   *reason = snes->reason;
4251184914b5SBarry Smith   PetscFunctionReturn(0);
4252184914b5SBarry Smith }
4253184914b5SBarry Smith 
4254c4421ceaSFande Kong /*@C
4255c4421ceaSFande Kong    SNESGetConvergedReasonString - Return a human readable string for snes converged reason
4256c4421ceaSFande Kong 
4257c4421ceaSFande Kong    Not Collective
4258c4421ceaSFande Kong 
4259c4421ceaSFande Kong    Input Parameter:
4260c4421ceaSFande Kong .  snes - the SNES context
4261c4421ceaSFande Kong 
4262c4421ceaSFande Kong    Output Parameter:
4263c4421ceaSFande Kong .  strreason - a human readable string that describes SNES converged reason
4264c4421ceaSFande Kong 
426599c90e12SSatish Balay    Level: beginner
4266c4421ceaSFande Kong 
4267db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`
4268c4421ceaSFande Kong @*/
4269c4421ceaSFande Kong PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason)
4270c4421ceaSFande Kong {
4271c4421ceaSFande Kong   PetscFunctionBegin;
4272c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4273dadcf809SJacob Faibussowitsch   PetscValidPointer(strreason,2);
4274c4421ceaSFande Kong   *strreason = SNESConvergedReasons[snes->reason];
4275c4421ceaSFande Kong   PetscFunctionReturn(0);
4276c4421ceaSFande Kong }
4277c4421ceaSFande Kong 
427833866048SMatthew G. Knepley /*@
427933866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
428033866048SMatthew G. Knepley 
428133866048SMatthew G. Knepley    Not Collective
428233866048SMatthew G. Knepley 
428333866048SMatthew G. Knepley    Input Parameters:
428433866048SMatthew G. Knepley +  snes - the SNES context
428533866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
428633866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
428733866048SMatthew G. Knepley 
428833866048SMatthew G. Knepley    Level: intermediate
428933866048SMatthew G. Knepley 
4290db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason`
429133866048SMatthew G. Knepley @*/
429233866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
429333866048SMatthew G. Knepley {
429433866048SMatthew G. Knepley   PetscFunctionBegin;
429533866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
429633866048SMatthew G. Knepley   snes->reason = reason;
429733866048SMatthew G. Knepley   PetscFunctionReturn(0);
429833866048SMatthew G. Knepley }
429933866048SMatthew G. Knepley 
4300c9005455SLois Curfman McInnes /*@
4301c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
4302c9005455SLois Curfman McInnes 
43033f9fe445SBarry Smith    Logically Collective on SNES
4304fee21e36SBarry Smith 
4305c7afd0dbSLois Curfman McInnes    Input Parameters:
4306c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
43078c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
4308cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
4309758f92a0SBarry Smith .  na  - size of a and its
431064731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
4311758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
4312c7afd0dbSLois Curfman McInnes 
4313308dcc3eSBarry Smith    Notes:
43140298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
4315308dcc3eSBarry Smith    default array of length 10000 is allocated.
4316308dcc3eSBarry Smith 
4317c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
4318c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
4319c9005455SLois Curfman McInnes    during the section of code that is being timed.
4320c9005455SLois Curfman McInnes 
432136851e7fSLois Curfman McInnes    Level: intermediate
432236851e7fSLois Curfman McInnes 
4323db781477SPatrick Sanan .seealso: `SNESGetConvergenceHistory()`
4324758f92a0SBarry Smith 
4325c9005455SLois Curfman McInnes @*/
43267087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
4327c9005455SLois Curfman McInnes {
43283a40ed3dSBarry Smith   PetscFunctionBegin;
43290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4330064a246eSJacob Faibussowitsch   if (a) PetscValidRealPointer(a,2);
4331a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
43327a1ec6d4SBarry Smith   if (!a) {
4333308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
43349566063dSJacob Faibussowitsch     PetscCall(PetscCalloc2(na,&a,na,&its));
4335071fcb05SBarry Smith     snes->conv_hist_alloc = PETSC_TRUE;
4336308dcc3eSBarry Smith   }
4337c9005455SLois Curfman McInnes   snes->conv_hist       = a;
4338758f92a0SBarry Smith   snes->conv_hist_its   = its;
4339115dd874SBarry Smith   snes->conv_hist_max   = (size_t)na;
4340a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
4341758f92a0SBarry Smith   snes->conv_hist_reset = reset;
4342758f92a0SBarry Smith   PetscFunctionReturn(0);
4343758f92a0SBarry Smith }
4344758f92a0SBarry Smith 
4345308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4346c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
4347c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
434899e0435eSBarry Smith 
43498cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4350308dcc3eSBarry Smith {
4351308dcc3eSBarry Smith   mxArray   *mat;
4352308dcc3eSBarry Smith   PetscInt  i;
4353308dcc3eSBarry Smith   PetscReal *ar;
4354308dcc3eSBarry Smith 
4355308dcc3eSBarry Smith   PetscFunctionBegin;
4356308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
4357308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
4358f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4359308dcc3eSBarry Smith   PetscFunctionReturn(mat);
4360308dcc3eSBarry Smith }
4361308dcc3eSBarry Smith #endif
4362308dcc3eSBarry Smith 
43630c4c9dddSBarry Smith /*@C
4364758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4365758f92a0SBarry Smith 
43663f9fe445SBarry Smith    Not Collective
4367758f92a0SBarry Smith 
4368758f92a0SBarry Smith    Input Parameter:
4369758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
4370758f92a0SBarry Smith 
4371758f92a0SBarry Smith    Output Parameters:
4372a2b725a8SWilliam Gropp +  a   - array to hold history
4373758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
4374758f92a0SBarry Smith          negative if not converged) for each solve.
4375758f92a0SBarry Smith -  na  - size of a and its
4376758f92a0SBarry Smith 
4377758f92a0SBarry Smith    Notes:
4378758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
4379758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4380758f92a0SBarry Smith 
4381758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
4382758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
4383758f92a0SBarry Smith    during the section of code that is being timed.
4384758f92a0SBarry Smith 
4385758f92a0SBarry Smith    Level: intermediate
4386758f92a0SBarry Smith 
4387db781477SPatrick Sanan .seealso: `SNESSetConvergenceHistory()`
4388758f92a0SBarry Smith 
4389758f92a0SBarry Smith @*/
43907087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
4391758f92a0SBarry Smith {
4392758f92a0SBarry Smith   PetscFunctionBegin;
43930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4394758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
4395758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
4396115dd874SBarry Smith   if (na)  *na  = (PetscInt) snes->conv_hist_len;
43973a40ed3dSBarry Smith   PetscFunctionReturn(0);
4398c9005455SLois Curfman McInnes }
4399c9005455SLois Curfman McInnes 
4400ac226902SBarry Smith /*@C
440176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
4402eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
44037e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
440476b2cf59SMatthew Knepley 
44053f9fe445SBarry Smith   Logically Collective on SNES
440676b2cf59SMatthew Knepley 
440776b2cf59SMatthew Knepley   Input Parameters:
4408a2b725a8SWilliam Gropp + snes - The nonlinear solver context
4409a2b725a8SWilliam Gropp - func - The function
441076b2cf59SMatthew Knepley 
441176b2cf59SMatthew Knepley   Calling sequence of func:
4412a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step);
441376b2cf59SMatthew Knepley 
441476b2cf59SMatthew Knepley . step - The current step of the iteration
441576b2cf59SMatthew Knepley 
4416fe97e370SBarry Smith   Level: advanced
4417fe97e370SBarry Smith 
44186b7fb656SBarry Smith   Note:
44196b7fb656SBarry Smith      This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction()
4420fe97e370SBarry Smith      This is not used by most users.
442176b2cf59SMatthew Knepley 
44226b7fb656SBarry 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.
44236b7fb656SBarry Smith 
4424db781477SPatrick Sanan .seealso `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`,
4425db781477SPatrick Sanan          `SNESMonitorSet()`, `SNESSetDivergenceTest()`
442676b2cf59SMatthew Knepley @*/
44277087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
442876b2cf59SMatthew Knepley {
442976b2cf59SMatthew Knepley   PetscFunctionBegin;
44300700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
4431e7788613SBarry Smith   snes->ops->update = func;
443276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
443376b2cf59SMatthew Knepley }
443476b2cf59SMatthew Knepley 
44359b94acceSBarry Smith /*
44369b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
44379b94acceSBarry Smith    positive parameter delta.
44389b94acceSBarry Smith 
44399b94acceSBarry Smith     Input Parameters:
4440c7afd0dbSLois Curfman McInnes +   snes - the SNES context
44419b94acceSBarry Smith .   y - approximate solution of linear system
44429b94acceSBarry Smith .   fnorm - 2-norm of current function
4443c7afd0dbSLois Curfman McInnes -   delta - trust region size
44449b94acceSBarry Smith 
44459b94acceSBarry Smith     Output Parameters:
4446c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
44479b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
44489b94acceSBarry Smith     region, and exceeds zero otherwise.
4449c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
44509b94acceSBarry Smith 
44519b94acceSBarry Smith     Note:
445204d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
44539b94acceSBarry Smith     is set to be the maximum allowable step size.
44549b94acceSBarry Smith 
44559b94acceSBarry Smith */
4456dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
44579b94acceSBarry Smith {
4458064f8208SBarry Smith   PetscReal      nrm;
4459ea709b57SSatish Balay   PetscScalar    cnorm;
44603a40ed3dSBarry Smith 
44613a40ed3dSBarry Smith   PetscFunctionBegin;
44620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44630700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4464c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
4465184914b5SBarry Smith 
44669566063dSJacob Faibussowitsch   PetscCall(VecNorm(y,NORM_2,&nrm));
4467064f8208SBarry Smith   if (nrm > *delta) {
4468064f8208SBarry Smith     nrm     = *delta/nrm;
4469064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
4470064f8208SBarry Smith     cnorm   = nrm;
44719566063dSJacob Faibussowitsch     PetscCall(VecScale(y,cnorm));
44729b94acceSBarry Smith     *ynorm  = *delta;
44739b94acceSBarry Smith   } else {
44749b94acceSBarry Smith     *gpnorm = 0.0;
4475064f8208SBarry Smith     *ynorm  = nrm;
44769b94acceSBarry Smith   }
44773a40ed3dSBarry Smith   PetscFunctionReturn(0);
44789b94acceSBarry Smith }
44799b94acceSBarry Smith 
448091f3e32bSBarry Smith /*@C
448119a666eeSBarry Smith    SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer
44822a359c20SBarry Smith 
44832a359c20SBarry Smith    Collective on SNES
44842a359c20SBarry Smith 
44852a359c20SBarry Smith    Parameter:
44862a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
44872a359c20SBarry Smith -  viewer - the viewer to display the reason
44882a359c20SBarry Smith 
44892a359c20SBarry Smith    Options Database Keys:
4490ee300463SSatish Balay +  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
4491ee300463SSatish Balay -  -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4492eafd5ff0SAlex Lindsay 
449319a666eeSBarry Smith   Notes:
449419a666eeSBarry Smith      To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default,
449519a666eeSBarry Smith      use PETSC_VIEWER_FAILED to only display a reason if it fails.
44962a359c20SBarry Smith 
44972a359c20SBarry Smith    Level: beginner
44982a359c20SBarry Smith 
4499db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonViewFromOptions()`,
4500db781477SPatrick Sanan           `PetscViewerPushFormat()`, `PetscViewerPopFormat()`
45012a359c20SBarry Smith 
45022a359c20SBarry Smith @*/
450319a666eeSBarry Smith PetscErrorCode  SNESConvergedReasonView(SNES snes,PetscViewer viewer)
45042a359c20SBarry Smith {
450575cca76cSMatthew G. Knepley   PetscViewerFormat format;
45062a359c20SBarry Smith   PetscBool         isAscii;
45072a359c20SBarry Smith 
45082a359c20SBarry Smith   PetscFunctionBegin;
450919a666eeSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
45109566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii));
45112a359c20SBarry Smith   if (isAscii) {
45129566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(viewer, &format));
45139566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel));
451475cca76cSMatthew G. Knepley     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
451575cca76cSMatthew G. Knepley       DM              dm;
451675cca76cSMatthew G. Knepley       Vec             u;
451775cca76cSMatthew G. Knepley       PetscDS         prob;
451875cca76cSMatthew G. Knepley       PetscInt        Nf, f;
451995cbbfd3SMatthew G. Knepley       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
452095cbbfd3SMatthew G. Knepley       void            **exactCtx;
452175cca76cSMatthew G. Knepley       PetscReal       error;
452275cca76cSMatthew G. Knepley 
45239566063dSJacob Faibussowitsch       PetscCall(SNESGetDM(snes, &dm));
45249566063dSJacob Faibussowitsch       PetscCall(SNESGetSolution(snes, &u));
45259566063dSJacob Faibussowitsch       PetscCall(DMGetDS(dm, &prob));
45269566063dSJacob Faibussowitsch       PetscCall(PetscDSGetNumFields(prob, &Nf));
45279566063dSJacob Faibussowitsch       PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx));
45289566063dSJacob Faibussowitsch       for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]));
45299566063dSJacob Faibussowitsch       PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error));
45309566063dSJacob Faibussowitsch       PetscCall(PetscFree2(exactSol, exactCtx));
45319566063dSJacob Faibussowitsch       if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n"));
453263a3b9bcSJacob Faibussowitsch       else                 PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error));
453375cca76cSMatthew G. Knepley     }
4534eafd5ff0SAlex Lindsay     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
45352a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
453663a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter));
45372a359c20SBarry Smith       } else {
453863a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter));
45392a359c20SBarry Smith       }
4540eafd5ff0SAlex Lindsay     } else if (snes->reason <= 0) {
45412a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
454263a3b9bcSJacob 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));
45432a359c20SBarry Smith       } else {
454463a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter));
45452a359c20SBarry Smith       }
45462a359c20SBarry Smith     }
45479566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel));
45482a359c20SBarry Smith   }
45492a359c20SBarry Smith   PetscFunctionReturn(0);
45502a359c20SBarry Smith }
45512a359c20SBarry Smith 
4552c4421ceaSFande Kong /*@C
4553c4421ceaSFande Kong    SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4554c4421ceaSFande Kong     end of the nonlinear solver to display the conver reason of the nonlinear solver.
4555c4421ceaSFande Kong 
4556c4421ceaSFande Kong    Logically Collective on SNES
4557c4421ceaSFande Kong 
4558c4421ceaSFande Kong    Input Parameters:
4559c4421ceaSFande Kong +  snes - the SNES context
4560c4421ceaSFande Kong .  f - the snes converged reason view function
4561c4421ceaSFande Kong .  vctx - [optional] user-defined context for private data for the
4562c4421ceaSFande Kong           snes converged reason view routine (use NULL if no context is desired)
4563c4421ceaSFande Kong -  reasonviewdestroy - [optional] routine that frees reasonview context
4564c4421ceaSFande Kong           (may be NULL)
4565c4421ceaSFande Kong 
4566c4421ceaSFande Kong    Options Database Keys:
4567c4421ceaSFande Kong +    -snes_converged_reason        - sets a default SNESConvergedReasonView()
4568c4421ceaSFande Kong -    -snes_converged_reason_view_cancel - cancels all converged reason viewers that have
4569c4421ceaSFande Kong                             been hardwired into a code by
4570c4421ceaSFande Kong                             calls to SNESConvergedReasonViewSet(), but
4571c4421ceaSFande Kong                             does not cancel those set via
4572c4421ceaSFande Kong                             the options database.
4573c4421ceaSFande Kong 
4574c4421ceaSFande Kong    Notes:
4575c4421ceaSFande Kong    Several different converged reason view routines may be set by calling
4576c4421ceaSFande Kong    SNESConvergedReasonViewSet() multiple times; all will be called in the
4577c4421ceaSFande Kong    order in which they were set.
4578c4421ceaSFande Kong 
4579c4421ceaSFande Kong    Level: intermediate
4580c4421ceaSFande Kong 
4581db781477SPatrick Sanan .seealso: `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()`
4582c4421ceaSFande Kong @*/
4583c4421ceaSFande Kong PetscErrorCode  SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**))
4584c4421ceaSFande Kong {
4585c4421ceaSFande Kong   PetscInt       i;
4586c4421ceaSFande Kong   PetscBool      identical;
4587c4421ceaSFande Kong 
4588c4421ceaSFande Kong   PetscFunctionBegin;
4589c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4590c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews;i++) {
45919566063dSJacob Faibussowitsch     PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical));
4592c4421ceaSFande Kong     if (identical) PetscFunctionReturn(0);
4593c4421ceaSFande Kong   }
45945f80ce2aSJacob Faibussowitsch   PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set");
4595c4421ceaSFande Kong   snes->reasonview[snes->numberreasonviews]          = f;
4596c4421ceaSFande Kong   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4597c4421ceaSFande Kong   snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx;
4598c4421ceaSFande Kong   PetscFunctionReturn(0);
4599c4421ceaSFande Kong }
4600c4421ceaSFande Kong 
460191f3e32bSBarry Smith /*@
460219a666eeSBarry Smith   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
4603c4421ceaSFande Kong                                        All the user-provided convergedReasonView routines will be involved as well, if they exist.
46042a359c20SBarry Smith 
46052a359c20SBarry Smith   Collective on SNES
46062a359c20SBarry Smith 
46072a359c20SBarry Smith   Input Parameters:
46082a359c20SBarry Smith . snes   - the SNES object
46092a359c20SBarry Smith 
46102a359c20SBarry Smith   Level: intermediate
46112a359c20SBarry Smith 
4612db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`
461319a666eeSBarry Smith 
46142a359c20SBarry Smith @*/
461519a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
46162a359c20SBarry Smith {
46172a359c20SBarry Smith   PetscViewer       viewer;
46182a359c20SBarry Smith   PetscBool         flg;
46192a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
46202a359c20SBarry Smith   PetscViewerFormat format;
4621c4421ceaSFande Kong   PetscInt          i;
46222a359c20SBarry Smith 
46232a359c20SBarry Smith   PetscFunctionBegin;
46242a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
46252a359c20SBarry Smith   incall = PETSC_TRUE;
4626c4421ceaSFande Kong 
4627c4421ceaSFande Kong   /* All user-provided viewers are called first, if they exist. */
4628c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews; i++) {
46299566063dSJacob Faibussowitsch     PetscCall((*snes->reasonview[i])(snes,snes->reasonviewcontext[i]));
4630c4421ceaSFande Kong   }
4631c4421ceaSFande Kong 
4632c4421ceaSFande Kong   /* Call PETSc default routine if users ask for it */
46339566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg));
46342a359c20SBarry Smith   if (flg) {
46359566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer,format));
46369566063dSJacob Faibussowitsch     PetscCall(SNESConvergedReasonView(snes,viewer));
46379566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
46389566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
46392a359c20SBarry Smith   }
46402a359c20SBarry Smith   incall = PETSC_FALSE;
46412a359c20SBarry Smith   PetscFunctionReturn(0);
46422a359c20SBarry Smith }
46432a359c20SBarry Smith 
4644487a658cSBarry Smith /*@
4645f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
4646f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
46479b94acceSBarry Smith 
4648c7afd0dbSLois Curfman McInnes    Collective on SNES
4649c7afd0dbSLois Curfman McInnes 
4650b2002411SLois Curfman McInnes    Input Parameters:
4651c7afd0dbSLois Curfman McInnes +  snes - the SNES context
46520298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
465385385478SLisandro Dalcin -  x - the solution vector.
46549b94acceSBarry Smith 
4655b2002411SLois Curfman McInnes    Notes:
46568ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
46576b7fb656SBarry Smith    for the nonlinear solve prior to calling SNESSolve().  In particular,
46588ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
46598ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
46608ddd3da0SLois Curfman McInnes 
466136851e7fSLois Curfman McInnes    Level: beginner
466236851e7fSLois Curfman McInnes 
4663db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`,
4664db781477SPatrick Sanan           `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`,
4665db781477SPatrick Sanan           `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()`
46669b94acceSBarry Smith @*/
46677087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
46689b94acceSBarry Smith {
4669ace3abfcSBarry Smith   PetscBool         flg;
4670efd51863SBarry Smith   PetscInt          grid;
46710298fd71SBarry Smith   Vec               xcreated = NULL;
4672caa4e7f2SJed Brown   DM                dm;
4673052efed2SBarry Smith 
46743a40ed3dSBarry Smith   PetscFunctionBegin;
46750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4676a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4677a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
46780700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
467985385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
468085385478SLisandro Dalcin 
468134b4d3a8SMatthew G. Knepley   /* High level operations using the nonlinear solver */
468206fc46c8SMatthew G. Knepley   {
468306fc46c8SMatthew G. Knepley     PetscViewer       viewer;
468406fc46c8SMatthew G. Knepley     PetscViewerFormat format;
46857c88af5aSMatthew G. Knepley     PetscInt          num;
468606fc46c8SMatthew G. Knepley     PetscBool         flg;
468706fc46c8SMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
468806fc46c8SMatthew G. Knepley 
468906fc46c8SMatthew G. Knepley     if (!incall) {
469034b4d3a8SMatthew G. Knepley       /* Estimate the convergence rate of the discretization */
46919566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg));
469206fc46c8SMatthew G. Knepley       if (flg) {
469306fc46c8SMatthew G. Knepley         PetscConvEst conv;
469446079b62SMatthew G. Knepley         DM           dm;
469546079b62SMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
469646079b62SMatthew G. Knepley         PetscInt     Nf;
469706fc46c8SMatthew G. Knepley 
469806fc46c8SMatthew G. Knepley         incall = PETSC_TRUE;
46999566063dSJacob Faibussowitsch         PetscCall(SNESGetDM(snes, &dm));
47009566063dSJacob Faibussowitsch         PetscCall(DMGetNumFields(dm, &Nf));
47019566063dSJacob Faibussowitsch         PetscCall(PetscCalloc1(Nf, &alpha));
47029566063dSJacob Faibussowitsch         PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv));
47039566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetSolver(conv, (PetscObject) snes));
47049566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetFromOptions(conv));
47059566063dSJacob Faibussowitsch         PetscCall(PetscConvEstSetUp(conv));
47069566063dSJacob Faibussowitsch         PetscCall(PetscConvEstGetConvRate(conv, alpha));
47079566063dSJacob Faibussowitsch         PetscCall(PetscViewerPushFormat(viewer, format));
47089566063dSJacob Faibussowitsch         PetscCall(PetscConvEstRateView(conv, alpha, viewer));
47099566063dSJacob Faibussowitsch         PetscCall(PetscViewerPopFormat(viewer));
47109566063dSJacob Faibussowitsch         PetscCall(PetscViewerDestroy(&viewer));
47119566063dSJacob Faibussowitsch         PetscCall(PetscConvEstDestroy(&conv));
47129566063dSJacob Faibussowitsch         PetscCall(PetscFree(alpha));
471306fc46c8SMatthew G. Knepley         incall = PETSC_FALSE;
471406fc46c8SMatthew G. Knepley       }
471534b4d3a8SMatthew G. Knepley       /* Adaptively refine the initial grid */
4716b2588ea6SMatthew G. Knepley       num  = 1;
47179566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg));
471834b4d3a8SMatthew G. Knepley       if (flg) {
471934b4d3a8SMatthew G. Knepley         DMAdaptor adaptor;
472034b4d3a8SMatthew G. Knepley 
472134b4d3a8SMatthew G. Knepley         incall = PETSC_TRUE;
47229566063dSJacob Faibussowitsch         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
47239566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSolver(adaptor, snes));
47249566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
47259566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetFromOptions(adaptor));
47269566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetUp(adaptor));
47279566063dSJacob Faibussowitsch         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x));
47289566063dSJacob Faibussowitsch         PetscCall(DMAdaptorDestroy(&adaptor));
472934b4d3a8SMatthew G. Knepley         incall = PETSC_FALSE;
473034b4d3a8SMatthew G. Knepley       }
47317c88af5aSMatthew G. Knepley       /* Use grid sequencing to adapt */
47327c88af5aSMatthew G. Knepley       num  = 0;
47339566063dSJacob Faibussowitsch       PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL));
47347c88af5aSMatthew G. Knepley       if (num) {
47357c88af5aSMatthew G. Knepley         DMAdaptor adaptor;
47367c88af5aSMatthew G. Knepley 
47377c88af5aSMatthew G. Knepley         incall = PETSC_TRUE;
47389566063dSJacob Faibussowitsch         PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor));
47399566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSolver(adaptor, snes));
47409566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetSequenceLength(adaptor, num));
47419566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetFromOptions(adaptor));
47429566063dSJacob Faibussowitsch         PetscCall(DMAdaptorSetUp(adaptor));
47439566063dSJacob Faibussowitsch         PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x));
47449566063dSJacob Faibussowitsch         PetscCall(DMAdaptorDestroy(&adaptor));
47457c88af5aSMatthew G. Knepley         incall = PETSC_FALSE;
47467c88af5aSMatthew G. Knepley       }
474706fc46c8SMatthew G. Knepley     }
474806fc46c8SMatthew G. Knepley   }
474941e867a5SStefano Zampini   if (!x) { x = snes->vec_sol; }
4750caa4e7f2SJed Brown   if (!x) {
47519566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
47529566063dSJacob Faibussowitsch     PetscCall(DMCreateGlobalVector(dm,&xcreated));
4753a69afd8bSBarry Smith     x    = xcreated;
4754a69afd8bSBarry Smith   }
47559566063dSJacob Faibussowitsch   PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view_pre"));
4756f05ece33SBarry Smith 
47579566063dSJacob Faibussowitsch   for (grid=0; grid<snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4758efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
4759efd51863SBarry Smith 
476085385478SLisandro Dalcin     /* set solution vector */
47619566063dSJacob Faibussowitsch     if (!grid) PetscCall(PetscObjectReference((PetscObject)x));
47629566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_sol));
476385385478SLisandro Dalcin     snes->vec_sol = x;
47649566063dSJacob Faibussowitsch     PetscCall(SNESGetDM(snes,&dm));
4765caa4e7f2SJed Brown 
4766caa4e7f2SJed Brown     /* set affine vector if provided */
47679566063dSJacob Faibussowitsch     if (b) PetscCall(PetscObjectReference((PetscObject)b));
47689566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&snes->vec_rhs));
476985385478SLisandro Dalcin     snes->vec_rhs = b;
477085385478SLisandro Dalcin 
47715f80ce2aSJacob 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");
47725f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_func != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
47735f80ce2aSJacob Faibussowitsch     PetscCheck(snes->vec_rhs  != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
4774154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
47759566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_sol_update));
47769566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update));
4777154060b5SMatthew G. Knepley     }
47789566063dSJacob Faibussowitsch     PetscCall(DMShellSetGlobalVector(dm,snes->vec_sol));
47799566063dSJacob Faibussowitsch     PetscCall(SNESSetUp(snes));
47803f149594SLisandro Dalcin 
47817eee914bSBarry Smith     if (!grid) {
47827eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
47839566063dSJacob Faibussowitsch         PetscCall((*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP));
4784d25893d9SBarry Smith       }
4785dd568438SSatish Balay     }
4786d25893d9SBarry Smith 
4787abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4788971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4789d5e45103SBarry Smith 
47909566063dSJacob Faibussowitsch     PetscCall(PetscLogEventBegin(SNES_Solve,snes,0,0,0));
47919566063dSJacob Faibussowitsch     PetscCall((*snes->ops->solve)(snes));
47929566063dSJacob Faibussowitsch     PetscCall(PetscLogEventEnd(SNES_Solve,snes,0,0,0));
47935f80ce2aSJacob Faibussowitsch     PetscCheck(snes->reason,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4794422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
47953f149594SLisandro Dalcin 
479637ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
479737ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
479837ec4e1aSPeter Brune 
47999566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg));
48009566063dSJacob Faibussowitsch     if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes));
4801c4421ceaSFande Kong     /* Call converged reason views. This may involve user-provided viewers as well */
48029566063dSJacob Faibussowitsch     PetscCall(SNESConvergedReasonViewFromOptions(snes));
48035968eb51SBarry Smith 
48045f80ce2aSJacob Faibussowitsch     if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
48059c8e83a9SBarry Smith     if (snes->reason < 0) break;
4806efd51863SBarry Smith     if (grid < snes->gridsequence) {
4807efd51863SBarry Smith       DM  fine;
4808efd51863SBarry Smith       Vec xnew;
4809efd51863SBarry Smith       Mat interp;
4810efd51863SBarry Smith 
48119566063dSJacob Faibussowitsch       PetscCall(DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine));
48125f80ce2aSJacob Faibussowitsch       PetscCheck(fine,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
48139566063dSJacob Faibussowitsch       PetscCall(DMCreateInterpolation(snes->dm,fine,&interp,NULL));
48149566063dSJacob Faibussowitsch       PetscCall(DMCreateGlobalVector(fine,&xnew));
48159566063dSJacob Faibussowitsch       PetscCall(MatInterpolate(interp,x,xnew));
48169566063dSJacob Faibussowitsch       PetscCall(DMInterpolate(snes->dm,interp,fine));
48179566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&interp));
4818efd51863SBarry Smith       x    = xnew;
4819efd51863SBarry Smith 
48209566063dSJacob Faibussowitsch       PetscCall(SNESReset(snes));
48219566063dSJacob Faibussowitsch       PetscCall(SNESSetDM(snes,fine));
48229566063dSJacob Faibussowitsch       PetscCall(SNESResetFromOptions(snes));
48239566063dSJacob Faibussowitsch       PetscCall(DMDestroy(&fine));
48249566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes))));
4825efd51863SBarry Smith     }
4826efd51863SBarry Smith   }
48279566063dSJacob Faibussowitsch   PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view"));
48289566063dSJacob Faibussowitsch   PetscCall(VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution"));
48299566063dSJacob Faibussowitsch   PetscCall(DMMonitor(snes->dm));
48309566063dSJacob Faibussowitsch   PetscCall(SNESMonitorPauseFinal_Internal(snes));
48313f7e2da0SPeter Brune 
48329566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&xcreated));
48339566063dSJacob Faibussowitsch   PetscCall(PetscObjectSAWsBlock((PetscObject)snes));
48343a40ed3dSBarry Smith   PetscFunctionReturn(0);
48359b94acceSBarry Smith }
48369b94acceSBarry Smith 
48379b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
48389b94acceSBarry Smith 
483982bf6240SBarry Smith /*@C
48404b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
48419b94acceSBarry Smith 
4842fee21e36SBarry Smith    Collective on SNES
4843fee21e36SBarry Smith 
4844c7afd0dbSLois Curfman McInnes    Input Parameters:
4845c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4846454a90a3SBarry Smith -  type - a known method
4847c7afd0dbSLois Curfman McInnes 
4848c7afd0dbSLois Curfman McInnes    Options Database Key:
4849454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
485004d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4851ae12b187SLois Curfman McInnes 
48529b94acceSBarry Smith    Notes:
4853e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
485404d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4855c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
4856a2b725a8SWilliam Gropp -    SNESNEWTONTR - Newton's method with trust region
4857c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
48589b94acceSBarry Smith 
4859ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4860ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4861ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4862ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4863ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4864ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4865ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4866ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4867ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4868b0a32e0cSBarry Smith   appropriate method.
486936851e7fSLois Curfman McInnes 
487095452b02SPatrick Sanan     Developer Notes:
487195452b02SPatrick Sanan     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
48728f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
48738f6c3df8SBarry Smith 
487436851e7fSLois Curfman McInnes   Level: intermediate
4875a703fe33SLois Curfman McInnes 
4876db781477SPatrick Sanan .seealso: `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()`
4877435da068SBarry Smith 
48789b94acceSBarry Smith @*/
487919fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
48809b94acceSBarry Smith {
4881ace3abfcSBarry Smith   PetscBool      match;
48825f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(SNES);
48833a40ed3dSBarry Smith 
48843a40ed3dSBarry Smith   PetscFunctionBegin;
48850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48864482741eSBarry Smith   PetscValidCharPointer(type,2);
488782bf6240SBarry Smith 
48889566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)snes,type,&match));
48890f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
489092ff6ae8SBarry Smith 
48919566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(SNESList,type,&r));
48925f80ce2aSJacob Faibussowitsch   PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
489375396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4894*a958fbfcSStefano Zampini   if (snes->ops->destroy) PetscCall((*snes->ops->destroy)(snes));
489575396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
48969e5d0892SLisandro Dalcin   snes->ops->setup          = NULL;
48979e5d0892SLisandro Dalcin   snes->ops->solve          = NULL;
48989e5d0892SLisandro Dalcin   snes->ops->view           = NULL;
48999e5d0892SLisandro Dalcin   snes->ops->setfromoptions = NULL;
49009e5d0892SLisandro Dalcin   snes->ops->destroy        = NULL;
49017fe760d5SStefano Zampini 
49027fe760d5SStefano Zampini   /* It may happen the user has customized the line search before calling SNESSetType */
49039566063dSJacob Faibussowitsch   if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch));
49047fe760d5SStefano Zampini 
490575396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
490675396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4907f5af7f23SKarl Rupp 
49089566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)snes,type));
49099566063dSJacob Faibussowitsch   PetscCall((*r)(snes));
49103a40ed3dSBarry Smith   PetscFunctionReturn(0);
49119b94acceSBarry Smith }
49129b94acceSBarry Smith 
49139b94acceSBarry Smith /*@C
49149a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
49159b94acceSBarry Smith 
4916c7afd0dbSLois Curfman McInnes    Not Collective
4917c7afd0dbSLois Curfman McInnes 
49189b94acceSBarry Smith    Input Parameter:
49194b0e389bSBarry Smith .  snes - nonlinear solver context
49209b94acceSBarry Smith 
49219b94acceSBarry Smith    Output Parameter:
49223a7fca6bSBarry Smith .  type - SNES method (a character string)
49239b94acceSBarry Smith 
492436851e7fSLois Curfman McInnes    Level: intermediate
492536851e7fSLois Curfman McInnes 
49269b94acceSBarry Smith @*/
492719fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
49289b94acceSBarry Smith {
49293a40ed3dSBarry Smith   PetscFunctionBegin;
49300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
49314482741eSBarry Smith   PetscValidPointer(type,2);
49327adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
49333a40ed3dSBarry Smith   PetscFunctionReturn(0);
49349b94acceSBarry Smith }
49359b94acceSBarry Smith 
49363cd8a7caSMatthew G. Knepley /*@
49373cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
49383cd8a7caSMatthew G. Knepley 
4939d083f849SBarry Smith   Logically Collective on SNES
49403cd8a7caSMatthew G. Knepley 
49413cd8a7caSMatthew G. Knepley   Input Parameters:
49423cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
49433cd8a7caSMatthew G. Knepley - u    - the solution vector
49443cd8a7caSMatthew G. Knepley 
49453cd8a7caSMatthew G. Knepley   Level: beginner
49463cd8a7caSMatthew G. Knepley 
49473cd8a7caSMatthew G. Knepley @*/
49483cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
49493cd8a7caSMatthew G. Knepley {
49503cd8a7caSMatthew G. Knepley   DM             dm;
49513cd8a7caSMatthew G. Knepley 
49523cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
49533cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
49543cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
49559566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) u));
49569566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&snes->vec_sol));
49573cd8a7caSMatthew G. Knepley 
49583cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
49593cd8a7caSMatthew G. Knepley 
49609566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes, &dm));
49619566063dSJacob Faibussowitsch   PetscCall(DMShellSetGlobalVector(dm, u));
49623cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
49633cd8a7caSMatthew G. Knepley }
49643cd8a7caSMatthew G. Knepley 
496552baeb72SSatish Balay /*@
49669b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4967c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
49689b94acceSBarry Smith 
4969c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4970c7afd0dbSLois Curfman McInnes 
49719b94acceSBarry Smith    Input Parameter:
49729b94acceSBarry Smith .  snes - the SNES context
49739b94acceSBarry Smith 
49749b94acceSBarry Smith    Output Parameter:
49759b94acceSBarry Smith .  x - the solution
49769b94acceSBarry Smith 
497770e92668SMatthew Knepley    Level: intermediate
497836851e7fSLois Curfman McInnes 
4979db781477SPatrick Sanan .seealso: `SNESGetSolutionUpdate()`, `SNESGetFunction()`
49809b94acceSBarry Smith @*/
49817087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
49829b94acceSBarry Smith {
49833a40ed3dSBarry Smith   PetscFunctionBegin;
49840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
49854482741eSBarry Smith   PetscValidPointer(x,2);
498685385478SLisandro Dalcin   *x = snes->vec_sol;
498770e92668SMatthew Knepley   PetscFunctionReturn(0);
498870e92668SMatthew Knepley }
498970e92668SMatthew Knepley 
499052baeb72SSatish Balay /*@
49919b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
49929b94acceSBarry Smith    stored.
49939b94acceSBarry Smith 
4994c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4995c7afd0dbSLois Curfman McInnes 
49969b94acceSBarry Smith    Input Parameter:
49979b94acceSBarry Smith .  snes - the SNES context
49989b94acceSBarry Smith 
49999b94acceSBarry Smith    Output Parameter:
50009b94acceSBarry Smith .  x - the solution update
50019b94acceSBarry Smith 
500236851e7fSLois Curfman McInnes    Level: advanced
500336851e7fSLois Curfman McInnes 
5004db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()`
50059b94acceSBarry Smith @*/
50067087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
50079b94acceSBarry Smith {
50083a40ed3dSBarry Smith   PetscFunctionBegin;
50090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
50104482741eSBarry Smith   PetscValidPointer(x,2);
501185385478SLisandro Dalcin   *x = snes->vec_sol_update;
50123a40ed3dSBarry Smith   PetscFunctionReturn(0);
50139b94acceSBarry Smith }
50149b94acceSBarry Smith 
50159b94acceSBarry Smith /*@C
50163638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
50179b94acceSBarry Smith 
5018a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
5019c7afd0dbSLois Curfman McInnes 
50209b94acceSBarry Smith    Input Parameter:
50219b94acceSBarry Smith .  snes - the SNES context
50229b94acceSBarry Smith 
5023d8d19677SJose E. Roman    Output Parameters:
50240298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
5025f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
50260298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
50279b94acceSBarry Smith 
502836851e7fSLois Curfman McInnes    Level: advanced
502936851e7fSLois Curfman McInnes 
503004edfde5SBarry Smith     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function
503104edfde5SBarry Smith 
5032db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction`
50339b94acceSBarry Smith @*/
5034f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
50359b94acceSBarry Smith {
50366cab3a1bSJed Brown   DM             dm;
5037a63bb30eSJed Brown 
50383a40ed3dSBarry Smith   PetscFunctionBegin;
50390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5040a63bb30eSJed Brown   if (r) {
5041a63bb30eSJed Brown     if (!snes->vec_func) {
5042a63bb30eSJed Brown       if (snes->vec_rhs) {
50439566063dSJacob Faibussowitsch         PetscCall(VecDuplicate(snes->vec_rhs,&snes->vec_func));
5044a63bb30eSJed Brown       } else if (snes->vec_sol) {
50459566063dSJacob Faibussowitsch         PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_func));
5046a63bb30eSJed Brown       } else if (snes->dm) {
50479566063dSJacob Faibussowitsch         PetscCall(DMCreateGlobalVector(snes->dm,&snes->vec_func));
5048a63bb30eSJed Brown       }
5049a63bb30eSJed Brown     }
5050a63bb30eSJed Brown     *r = snes->vec_func;
5051a63bb30eSJed Brown   }
50529566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
50539566063dSJacob Faibussowitsch   PetscCall(DMSNESGetFunction(dm,f,ctx));
50543a40ed3dSBarry Smith   PetscFunctionReturn(0);
50559b94acceSBarry Smith }
50569b94acceSBarry Smith 
5057c79ef259SPeter Brune /*@C
5058be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
5059c79ef259SPeter Brune 
5060c79ef259SPeter Brune    Input Parameter:
5061c79ef259SPeter Brune .  snes - the SNES context
5062c79ef259SPeter Brune 
5063d8d19677SJose E. Roman    Output Parameters:
5064be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
50650298fd71SBarry Smith -  ctx    - the function context (or NULL)
5066c79ef259SPeter Brune 
5067c79ef259SPeter Brune    Level: advanced
5068c79ef259SPeter Brune 
5069db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()`
5070c79ef259SPeter Brune @*/
5071c79ef259SPeter Brune 
5072be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
5073646217ecSPeter Brune {
50746cab3a1bSJed Brown   DM             dm;
50756cab3a1bSJed Brown 
5076646217ecSPeter Brune   PetscFunctionBegin;
5077646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
50789566063dSJacob Faibussowitsch   PetscCall(SNESGetDM(snes,&dm));
50799566063dSJacob Faibussowitsch   PetscCall(DMSNESGetNGS(dm,f,ctx));
5080646217ecSPeter Brune   PetscFunctionReturn(0);
5081646217ecSPeter Brune }
5082646217ecSPeter Brune 
50833c7409f5SSatish Balay /*@C
50843c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
5085d850072dSLois Curfman McInnes    SNES options in the database.
50863c7409f5SSatish Balay 
50873f9fe445SBarry Smith    Logically Collective on SNES
5088fee21e36SBarry Smith 
5089d8d19677SJose E. Roman    Input Parameters:
5090c7afd0dbSLois Curfman McInnes +  snes - the SNES context
5091c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
5092c7afd0dbSLois Curfman McInnes 
5093d850072dSLois Curfman McInnes    Notes:
5094a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
5095c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
5096d850072dSLois Curfman McInnes 
509736851e7fSLois Curfman McInnes    Level: advanced
509836851e7fSLois Curfman McInnes 
5099db781477SPatrick Sanan .seealso: `SNESSetFromOptions()`
51003c7409f5SSatish Balay @*/
51017087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
51023c7409f5SSatish Balay {
51033a40ed3dSBarry Smith   PetscFunctionBegin;
51040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
51059566063dSJacob Faibussowitsch   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes,prefix));
51069566063dSJacob Faibussowitsch   if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
510735f5d045SPeter Brune   if (snes->linesearch) {
51089566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes,&snes->linesearch));
51099566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix));
511035f5d045SPeter Brune   }
51119566063dSJacob Faibussowitsch   PetscCall(KSPSetOptionsPrefix(snes->ksp,prefix));
51123a40ed3dSBarry Smith   PetscFunctionReturn(0);
51133c7409f5SSatish Balay }
51143c7409f5SSatish Balay 
51153c7409f5SSatish Balay /*@C
5116f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
5117d850072dSLois Curfman McInnes    SNES options in the database.
51183c7409f5SSatish Balay 
51193f9fe445SBarry Smith    Logically Collective on SNES
5120fee21e36SBarry Smith 
5121c7afd0dbSLois Curfman McInnes    Input Parameters:
5122c7afd0dbSLois Curfman McInnes +  snes - the SNES context
5123c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
5124c7afd0dbSLois Curfman McInnes 
5125d850072dSLois Curfman McInnes    Notes:
5126a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
5127c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
5128d850072dSLois Curfman McInnes 
512936851e7fSLois Curfman McInnes    Level: advanced
513036851e7fSLois Curfman McInnes 
5131db781477SPatrick Sanan .seealso: `SNESGetOptionsPrefix()`
51323c7409f5SSatish Balay @*/
51337087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
51343c7409f5SSatish Balay {
51353a40ed3dSBarry Smith   PetscFunctionBegin;
51360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
51379566063dSJacob Faibussowitsch   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix));
51389566063dSJacob Faibussowitsch   if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp));
513935f5d045SPeter Brune   if (snes->linesearch) {
51409566063dSJacob Faibussowitsch     PetscCall(SNESGetLineSearch(snes,&snes->linesearch));
51419566063dSJacob Faibussowitsch     PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix));
514235f5d045SPeter Brune   }
51439566063dSJacob Faibussowitsch   PetscCall(KSPAppendOptionsPrefix(snes->ksp,prefix));
51443a40ed3dSBarry Smith   PetscFunctionReturn(0);
51453c7409f5SSatish Balay }
51463c7409f5SSatish Balay 
51479ab63eb5SSatish Balay /*@C
51483c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
51493c7409f5SSatish Balay    SNES options in the database.
51503c7409f5SSatish Balay 
5151c7afd0dbSLois Curfman McInnes    Not Collective
5152c7afd0dbSLois Curfman McInnes 
51533c7409f5SSatish Balay    Input Parameter:
51543c7409f5SSatish Balay .  snes - the SNES context
51553c7409f5SSatish Balay 
51563c7409f5SSatish Balay    Output Parameter:
51573c7409f5SSatish Balay .  prefix - pointer to the prefix string used
51583c7409f5SSatish Balay 
515995452b02SPatrick Sanan    Notes:
516095452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
51619ab63eb5SSatish Balay    sufficient length to hold the prefix.
51629ab63eb5SSatish Balay 
516336851e7fSLois Curfman McInnes    Level: advanced
516436851e7fSLois Curfman McInnes 
5165db781477SPatrick Sanan .seealso: `SNESAppendOptionsPrefix()`
51663c7409f5SSatish Balay @*/
51677087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
51683c7409f5SSatish Balay {
51693a40ed3dSBarry Smith   PetscFunctionBegin;
51700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
51719566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes,prefix));
51723a40ed3dSBarry Smith   PetscFunctionReturn(0);
51733c7409f5SSatish Balay }
51743c7409f5SSatish Balay 
51753cea93caSBarry Smith /*@C
51761c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
51771c84c290SBarry Smith 
51781c84c290SBarry Smith    Not collective
51791c84c290SBarry Smith 
51801c84c290SBarry Smith    Input Parameters:
51811c84c290SBarry Smith +  name_solver - name of a new user-defined solver
51821c84c290SBarry Smith -  routine_create - routine to create method context
51831c84c290SBarry Smith 
51841c84c290SBarry Smith    Notes:
51851c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
51861c84c290SBarry Smith 
51871c84c290SBarry Smith    Sample usage:
51881c84c290SBarry Smith .vb
5189bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
51901c84c290SBarry Smith .ve
51911c84c290SBarry Smith 
51921c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
51931c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
51941c84c290SBarry Smith    or at runtime via the option
51951c84c290SBarry Smith $     -snes_type my_solver
51961c84c290SBarry Smith 
51971c84c290SBarry Smith    Level: advanced
51981c84c290SBarry Smith 
51991c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
52001c84c290SBarry Smith 
5201db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()`
52023cea93caSBarry Smith 
52037f6c08e0SMatthew Knepley   Level: advanced
52043cea93caSBarry Smith @*/
5205bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
5206b2002411SLois Curfman McInnes {
5207b2002411SLois Curfman McInnes   PetscFunctionBegin;
52089566063dSJacob Faibussowitsch   PetscCall(SNESInitializePackage());
52099566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListAdd(&SNESList,sname,function));
5210b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
5211b2002411SLois Curfman McInnes }
5212da9b6338SBarry Smith 
52137087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
5214da9b6338SBarry Smith {
521577431f27SBarry Smith   PetscInt       N,i,j;
5216da9b6338SBarry Smith   Vec            u,uh,fh;
5217da9b6338SBarry Smith   PetscScalar    value;
5218da9b6338SBarry Smith   PetscReal      norm;
5219da9b6338SBarry Smith 
5220da9b6338SBarry Smith   PetscFunctionBegin;
52219566063dSJacob Faibussowitsch   PetscCall(SNESGetSolution(snes,&u));
52229566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&uh));
52239566063dSJacob Faibussowitsch   PetscCall(VecDuplicate(u,&fh));
5224da9b6338SBarry Smith 
5225da9b6338SBarry Smith   /* currently only works for sequential */
52269566063dSJacob Faibussowitsch   PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n"));
52279566063dSJacob Faibussowitsch   PetscCall(VecGetSize(u,&N));
5228da9b6338SBarry Smith   for (i=0; i<N; i++) {
52299566063dSJacob Faibussowitsch     PetscCall(VecCopy(u,uh));
523063a3b9bcSJacob Faibussowitsch     PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %" PetscInt_FMT "\n",i));
5231da9b6338SBarry Smith     for (j=-10; j<11; j++) {
52328b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
52339566063dSJacob Faibussowitsch       PetscCall(VecSetValue(uh,i,value,ADD_VALUES));
52349566063dSJacob Faibussowitsch       PetscCall(SNESComputeFunction(snes,uh,fh));
52359566063dSJacob Faibussowitsch       PetscCall(VecNorm(fh,NORM_2,&norm));
523663a3b9bcSJacob Faibussowitsch       PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"       j norm %" PetscInt_FMT " %18.16e\n",j,(double)norm));
5237da9b6338SBarry Smith       value = -value;
52389566063dSJacob Faibussowitsch       PetscCall(VecSetValue(uh,i,value,ADD_VALUES));
5239da9b6338SBarry Smith     }
5240da9b6338SBarry Smith   }
52419566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&uh));
52429566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&fh));
5243da9b6338SBarry Smith   PetscFunctionReturn(0);
5244da9b6338SBarry Smith }
524571f87433Sdalcinl 
524671f87433Sdalcinl /*@
5247fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
524871f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
524971f87433Sdalcinl    Newton method.
525071f87433Sdalcinl 
52513f9fe445SBarry Smith    Logically Collective on SNES
525271f87433Sdalcinl 
525371f87433Sdalcinl    Input Parameters:
525471f87433Sdalcinl +  snes - SNES context
525571f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
525671f87433Sdalcinl 
525764ba62caSBarry Smith     Options Database:
525864ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
525964ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
526064ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
526164ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
526264ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
526364ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
526464ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
526564ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
526664ba62caSBarry Smith 
526771f87433Sdalcinl    Notes:
526871f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
526971f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
527071f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
527171f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
527271f87433Sdalcinl    solver.
527371f87433Sdalcinl 
527471f87433Sdalcinl    Level: advanced
527571f87433Sdalcinl 
527671f87433Sdalcinl    Reference:
527771f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
527871f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
527971f87433Sdalcinl 
5280db781477SPatrick Sanan .seealso: `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
528171f87433Sdalcinl @*/
52827087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
528371f87433Sdalcinl {
528471f87433Sdalcinl   PetscFunctionBegin;
52850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5286acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
528771f87433Sdalcinl   snes->ksp_ewconv = flag;
528871f87433Sdalcinl   PetscFunctionReturn(0);
528971f87433Sdalcinl }
529071f87433Sdalcinl 
529171f87433Sdalcinl /*@
5292fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
529371f87433Sdalcinl    for computing relative tolerance for linear solvers within an
529471f87433Sdalcinl    inexact Newton method.
529571f87433Sdalcinl 
529671f87433Sdalcinl    Not Collective
529771f87433Sdalcinl 
529871f87433Sdalcinl    Input Parameter:
529971f87433Sdalcinl .  snes - SNES context
530071f87433Sdalcinl 
530171f87433Sdalcinl    Output Parameter:
530271f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
530371f87433Sdalcinl 
530471f87433Sdalcinl    Notes:
530571f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
530671f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
530771f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
530871f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
530971f87433Sdalcinl    solver.
531071f87433Sdalcinl 
531171f87433Sdalcinl    Level: advanced
531271f87433Sdalcinl 
531371f87433Sdalcinl    Reference:
531471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
531571f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
531671f87433Sdalcinl 
5317db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()`
531871f87433Sdalcinl @*/
53197087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
532071f87433Sdalcinl {
532171f87433Sdalcinl   PetscFunctionBegin;
53220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5323534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag,2);
532471f87433Sdalcinl   *flag = snes->ksp_ewconv;
532571f87433Sdalcinl   PetscFunctionReturn(0);
532671f87433Sdalcinl }
532771f87433Sdalcinl 
532871f87433Sdalcinl /*@
5329fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
533071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
533171f87433Sdalcinl    Newton method.
533271f87433Sdalcinl 
53333f9fe445SBarry Smith    Logically Collective on SNES
533471f87433Sdalcinl 
533571f87433Sdalcinl    Input Parameters:
533671f87433Sdalcinl +    snes - SNES context
53370f0abf79SStefano Zampini .    version - version 1, 2 (default is 2), 3 or 4
533871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
533971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
534071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
534171f87433Sdalcinl              (0 <= gamma2 <= 1)
534271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
534371f87433Sdalcinl .    alpha2 - power for safeguard
534471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
534571f87433Sdalcinl 
534671f87433Sdalcinl    Note:
534771f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
534871f87433Sdalcinl 
534971f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
535071f87433Sdalcinl 
535171f87433Sdalcinl    Level: advanced
535271f87433Sdalcinl 
535371f87433Sdalcinl    Reference:
535471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
535571f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
535671f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
535771f87433Sdalcinl 
5358db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`
535971f87433Sdalcinl @*/
5360f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
536171f87433Sdalcinl {
5362fa9f3622SBarry Smith   SNESKSPEW *kctx;
53635fd66863SKarl Rupp 
536471f87433Sdalcinl   PetscFunctionBegin;
53650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5366fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
53675f80ce2aSJacob Faibussowitsch   PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5368c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
5369c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
5370c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
5371c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
5372c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
5373c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
5374c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
537571f87433Sdalcinl 
537671f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
537771f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
537871f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
537971f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
538071f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
538171f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
538271f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
538371f87433Sdalcinl 
53840f0abf79SStefano 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);
53850b121fc5SBarry 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);
53860b121fc5SBarry 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);
53870b121fc5SBarry 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);
53880b121fc5SBarry 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);
53890b121fc5SBarry 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);
539071f87433Sdalcinl   PetscFunctionReturn(0);
539171f87433Sdalcinl }
539271f87433Sdalcinl 
539371f87433Sdalcinl /*@
5394fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
539571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
539671f87433Sdalcinl    Newton method.
539771f87433Sdalcinl 
539871f87433Sdalcinl    Not Collective
539971f87433Sdalcinl 
540097bb3fdcSJose E. Roman    Input Parameter:
54016b867d5aSJose E. Roman .    snes - SNES context
540271f87433Sdalcinl 
540371f87433Sdalcinl    Output Parameters:
54040f0abf79SStefano Zampini +    version - version 1, 2 (default is 2), 3 or 4
540571f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
540671f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5407bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
540871f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
540971f87433Sdalcinl .    alpha2 - power for safeguard
541071f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
541171f87433Sdalcinl 
541271f87433Sdalcinl    Level: advanced
541371f87433Sdalcinl 
5414db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()`
541571f87433Sdalcinl @*/
5416bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
541771f87433Sdalcinl {
5418fa9f3622SBarry Smith   SNESKSPEW *kctx;
54195fd66863SKarl Rupp 
542071f87433Sdalcinl   PetscFunctionBegin;
54210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5422fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
54235f80ce2aSJacob Faibussowitsch   PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
542471f87433Sdalcinl   if (version)   *version   = kctx->version;
542571f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
542671f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
542771f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
542871f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
542971f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
543071f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
543171f87433Sdalcinl   PetscFunctionReturn(0);
543271f87433Sdalcinl }
543371f87433Sdalcinl 
5434d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
543571f87433Sdalcinl {
5436fa9f3622SBarry Smith   SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
543771f87433Sdalcinl   PetscReal rtol  = PETSC_DEFAULT,stol;
543871f87433Sdalcinl 
543971f87433Sdalcinl   PetscFunctionBegin;
5440d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
544130058271SDmitry Karpeev   if (!snes->iter) {
544230058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
54439566063dSJacob Faibussowitsch     PetscCall(VecNorm(snes->vec_func,NORM_2,&kctx->norm_first));
54440f0abf79SStefano Zampini   } else {
544571f87433Sdalcinl     if (kctx->version == 1) {
54460f0abf79SStefano Zampini       rtol = PetscAbsReal(snes->norm - kctx->lresid_last)/kctx->norm_last;
544785ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
544871f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
544971f87433Sdalcinl     } else if (kctx->version == 2) {
545085ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
545185ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
545271f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
545371f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
545485ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
545571f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
545685ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
545771f87433Sdalcinl       stol = PetscMax(rtol,stol);
545871f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
545971f87433Sdalcinl       /* safeguard: avoid oversolving */
546030058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
546171f87433Sdalcinl       stol = PetscMax(rtol,stol);
546271f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
54630f0abf79SStefano Zampini     } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */
54640f0abf79SStefano Zampini       PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm);
54650f0abf79SStefano Zampini       PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last);
54660f0abf79SStefano Zampini       PetscReal rk = ared / pred;
54670f0abf79SStefano Zampini       if (rk < kctx->v4_p1) rtol = 1. - 2.*kctx->v4_p1;
54680f0abf79SStefano Zampini       else if (rk < kctx->v4_p2) rtol = kctx->rtol_last;
54690f0abf79SStefano Zampini       else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last;
54700f0abf79SStefano Zampini       else rtol = kctx->v4_m2 * kctx->rtol_last;
54710f0abf79SStefano Zampini 
54720f0abf79SStefano Zampini       if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 &&
54730f0abf79SStefano Zampini           kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) {
54740f0abf79SStefano Zampini         rtol = kctx->v4_m4 * kctx->rtol_last;
54750f0abf79SStefano 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);
54760f0abf79SStefano Zampini       } else {
54770f0abf79SStefano 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);
547871f87433Sdalcinl       }
54790f0abf79SStefano Zampini       kctx->rtol_last_2 = kctx->rtol_last;
54800f0abf79SStefano Zampini       kctx->rk_last_2 = kctx->rk_last;
54810f0abf79SStefano Zampini       kctx->rk_last = rk;
54820f0abf79SStefano Zampini     } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1-4 are supported: %" PetscInt_FMT,kctx->version);
54830f0abf79SStefano Zampini   }
54840f0abf79SStefano Zampini   /* safeguard: avoid rtol greater than rtol_max */
548571f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
54869566063dSJacob Faibussowitsch   PetscCall(KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT));
548763a3b9bcSJacob Faibussowitsch   PetscCall(PetscInfo(snes,"iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol));
548871f87433Sdalcinl   PetscFunctionReturn(0);
548971f87433Sdalcinl }
549071f87433Sdalcinl 
5491d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
549271f87433Sdalcinl {
5493fa9f3622SBarry Smith   SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
549471f87433Sdalcinl   PCSide    pcside;
549571f87433Sdalcinl   Vec       lres;
549671f87433Sdalcinl 
549771f87433Sdalcinl   PetscFunctionBegin;
5498d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
54999566063dSJacob Faibussowitsch   PetscCall(KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL));
550071dbe336SPeter Brune   kctx->norm_last = snes->norm;
55010f0abf79SStefano Zampini   if (kctx->version == 1 || kctx->version == 4) {
55024f00ce20SMatthew G. Knepley     PC        pc;
55030f0abf79SStefano Zampini     PetscBool getRes;
55044f00ce20SMatthew G. Knepley 
55059566063dSJacob Faibussowitsch     PetscCall(KSPGetPC(ksp,&pc));
55060f0abf79SStefano Zampini     PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&getRes));
55070f0abf79SStefano Zampini     if (!getRes) {
55080f0abf79SStefano Zampini       KSPNormType normtype;
55090f0abf79SStefano Zampini 
55100f0abf79SStefano Zampini       PetscCall(KSPGetNormType(ksp,&normtype));
55110f0abf79SStefano Zampini       getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED);
55120f0abf79SStefano Zampini     }
55139566063dSJacob Faibussowitsch     PetscCall(KSPGetPCSide(ksp,&pcside));
55140f0abf79SStefano Zampini     if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */
55159566063dSJacob Faibussowitsch       PetscCall(KSPGetResidualNorm(ksp,&kctx->lresid_last));
551671f87433Sdalcinl     } else {
551771f87433Sdalcinl       /* KSP residual is preconditioned residual */
551871f87433Sdalcinl       /* compute true linear residual norm */
55190f0abf79SStefano Zampini       Mat J;
55200f0abf79SStefano Zampini       PetscCall(KSPGetOperators(ksp,&J,NULL));
55219566063dSJacob Faibussowitsch       PetscCall(VecDuplicate(b,&lres));
55220f0abf79SStefano Zampini       PetscCall(MatMult(J,x,lres));
55239566063dSJacob Faibussowitsch       PetscCall(VecAYPX(lres,-1.0,b));
55249566063dSJacob Faibussowitsch       PetscCall(VecNorm(lres,NORM_2,&kctx->lresid_last));
55259566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&lres));
552671f87433Sdalcinl     }
552771f87433Sdalcinl   }
552871f87433Sdalcinl   PetscFunctionReturn(0);
552971f87433Sdalcinl }
553071f87433Sdalcinl 
5531d4211eb9SBarry Smith /*@
5532d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
5533d4211eb9SBarry Smith 
5534d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
5535d4211eb9SBarry Smith 
5536d4211eb9SBarry Smith    Input Parameter:
5537d4211eb9SBarry Smith .  snes - the SNES context
5538d4211eb9SBarry Smith 
5539d4211eb9SBarry Smith    Output Parameter:
5540d4211eb9SBarry Smith .  ksp - the KSP context
5541d4211eb9SBarry Smith 
5542d4211eb9SBarry Smith    Notes:
5543d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
5544d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
5545d4211eb9SBarry Smith    PC contexts as well.
5546d4211eb9SBarry Smith 
5547d4211eb9SBarry Smith    Level: beginner
5548d4211eb9SBarry Smith 
5549db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()`
5550d4211eb9SBarry Smith @*/
5551d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
555271f87433Sdalcinl {
555371f87433Sdalcinl   PetscFunctionBegin;
5554d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5555d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
5556d4211eb9SBarry Smith 
5557d4211eb9SBarry Smith   if (!snes->ksp) {
55589566063dSJacob Faibussowitsch     PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp));
55599566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1));
55609566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp));
5561d4211eb9SBarry Smith 
55629566063dSJacob Faibussowitsch     PetscCall(KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes));
55639566063dSJacob Faibussowitsch     PetscCall(KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes));
5564a5c2985bSBarry Smith 
55659566063dSJacob Faibussowitsch     PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes));
55669566063dSJacob Faibussowitsch     PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options));
5567d4211eb9SBarry Smith   }
5568d4211eb9SBarry Smith   *ksp = snes->ksp;
556971f87433Sdalcinl   PetscFunctionReturn(0);
557071f87433Sdalcinl }
55716c699258SBarry Smith 
5572af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
55736c699258SBarry Smith /*@
55742a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
55756c699258SBarry Smith 
55763f9fe445SBarry Smith    Logically Collective on SNES
55776c699258SBarry Smith 
55786c699258SBarry Smith    Input Parameters:
55792a808120SBarry Smith +  snes - the nonlinear solver context
55802a808120SBarry Smith -  dm - the dm, cannot be NULL
55816c699258SBarry Smith 
5582e03a659cSJed Brown    Notes:
5583e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
5584e03a659cSJed Brown    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
5585e03a659cSJed Brown    problems using the same function space.
5586e03a659cSJed Brown 
55876c699258SBarry Smith    Level: intermediate
55886c699258SBarry Smith 
5589db781477SPatrick Sanan .seealso: `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()`
55906c699258SBarry Smith @*/
55917087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
55926c699258SBarry Smith {
5593345fed2cSBarry Smith   KSP            ksp;
5594942e3340SBarry Smith   DMSNES         sdm;
55956c699258SBarry Smith 
55966c699258SBarry Smith   PetscFunctionBegin;
55970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55982a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
55999566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)dm));
5600942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
560151f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
56029566063dSJacob Faibussowitsch       PetscCall(DMCopyDMSNES(snes->dm,dm));
56039566063dSJacob Faibussowitsch       PetscCall(DMGetDMSNES(snes->dm,&sdm));
5604f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
56056cab3a1bSJed Brown     }
56069566063dSJacob Faibussowitsch     PetscCall(DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes));
56079566063dSJacob Faibussowitsch     PetscCall(DMDestroy(&snes->dm));
56086cab3a1bSJed Brown   }
56096c699258SBarry Smith   snes->dm     = dm;
5610116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
5611f5af7f23SKarl Rupp 
56129566063dSJacob Faibussowitsch   PetscCall(SNESGetKSP(snes,&ksp));
56139566063dSJacob Faibussowitsch   PetscCall(KSPSetDM(ksp,dm));
56149566063dSJacob Faibussowitsch   PetscCall(KSPSetDMActive(ksp,PETSC_FALSE));
5615efd4aadfSBarry Smith   if (snes->npc) {
56169566063dSJacob Faibussowitsch     PetscCall(SNESSetDM(snes->npc,snes->dm));
56179566063dSJacob Faibussowitsch     PetscCall(SNESSetNPCSide(snes,snes->npcside));
56182c155ee1SBarry Smith   }
56196c699258SBarry Smith   PetscFunctionReturn(0);
56206c699258SBarry Smith }
56216c699258SBarry Smith 
56226c699258SBarry Smith /*@
56236c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
56246c699258SBarry Smith 
56253f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
56266c699258SBarry Smith 
56276c699258SBarry Smith    Input Parameter:
56286c699258SBarry Smith . snes - the preconditioner context
56296c699258SBarry Smith 
56306c699258SBarry Smith    Output Parameter:
56316c699258SBarry Smith .  dm - the dm
56326c699258SBarry Smith 
56336c699258SBarry Smith    Level: intermediate
56346c699258SBarry Smith 
5635db781477SPatrick Sanan .seealso: `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()`
56366c699258SBarry Smith @*/
56377087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
56386c699258SBarry Smith {
56396c699258SBarry Smith   PetscFunctionBegin;
56400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
56416cab3a1bSJed Brown   if (!snes->dm) {
56429566063dSJacob Faibussowitsch     PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm));
5643116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
56446cab3a1bSJed Brown   }
56456c699258SBarry Smith   *dm = snes->dm;
56466c699258SBarry Smith   PetscFunctionReturn(0);
56476c699258SBarry Smith }
56480807856dSBarry Smith 
564931823bd8SMatthew G Knepley /*@
5650be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
565131823bd8SMatthew G Knepley 
565231823bd8SMatthew G Knepley   Collective on SNES
565331823bd8SMatthew G Knepley 
565431823bd8SMatthew G Knepley   Input Parameters:
565531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
565631823bd8SMatthew G Knepley - pc   - the preconditioner object
565731823bd8SMatthew G Knepley 
565831823bd8SMatthew G Knepley   Notes:
5659be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
566031823bd8SMatthew G Knepley   to configure it using the API).
566131823bd8SMatthew G Knepley 
566231823bd8SMatthew G Knepley   Level: developer
566331823bd8SMatthew G Knepley 
5664db781477SPatrick Sanan .seealso: `SNESGetNPC()`, `SNESHasNPC()`
566531823bd8SMatthew G Knepley @*/
5666be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
566731823bd8SMatthew G Knepley {
566831823bd8SMatthew G Knepley   PetscFunctionBegin;
566931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
567031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
567131823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
56729566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) pc));
56739566063dSJacob Faibussowitsch   PetscCall(SNESDestroy(&snes->npc));
5674efd4aadfSBarry Smith   snes->npc = pc;
56759566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc));
567631823bd8SMatthew G Knepley   PetscFunctionReturn(0);
567731823bd8SMatthew G Knepley }
567831823bd8SMatthew G Knepley 
567931823bd8SMatthew G Knepley /*@
5680be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
568131823bd8SMatthew G Knepley 
5682951fe5abSBarry Smith   Not Collective; but any changes to the obtained SNES object must be applied collectively
568331823bd8SMatthew G Knepley 
568431823bd8SMatthew G Knepley   Input Parameter:
568531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
568631823bd8SMatthew G Knepley 
568731823bd8SMatthew G Knepley   Output Parameter:
568831823bd8SMatthew G Knepley . pc - preconditioner context
568931823bd8SMatthew G Knepley 
5690b5badacbSBarry Smith   Options Database:
5691b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner
5692b5badacbSBarry Smith 
569395452b02SPatrick Sanan   Notes:
5694b5badacbSBarry Smith     If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created.
5695be95d8f1SBarry Smith 
5696951fe5abSBarry Smith     The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5697951fe5abSBarry Smith     SNES during SNESSetUp()
5698951fe5abSBarry Smith 
569931823bd8SMatthew G Knepley   Level: developer
570031823bd8SMatthew G Knepley 
5701db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()`
570231823bd8SMatthew G Knepley @*/
5703be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
570431823bd8SMatthew G Knepley {
5705a64e098fSPeter Brune   const char     *optionsprefix;
570631823bd8SMatthew G Knepley 
570731823bd8SMatthew G Knepley   PetscFunctionBegin;
570831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
570931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
5710efd4aadfSBarry Smith   if (!snes->npc) {
57119566063dSJacob Faibussowitsch     PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc));
57129566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1));
57139566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc));
57149566063dSJacob Faibussowitsch     PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix));
57159566063dSJacob Faibussowitsch     PetscCall(SNESSetOptionsPrefix(snes->npc,optionsprefix));
57169566063dSJacob Faibussowitsch     PetscCall(SNESAppendOptionsPrefix(snes->npc,"npc_"));
57179566063dSJacob Faibussowitsch     PetscCall(SNESSetCountersReset(snes->npc,PETSC_FALSE));
571831823bd8SMatthew G Knepley   }
5719efd4aadfSBarry Smith   *pc = snes->npc;
572031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
572131823bd8SMatthew G Knepley }
572231823bd8SMatthew G Knepley 
57233ad1a0b9SPatrick Farrell /*@
57243ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
57253ad1a0b9SPatrick Farrell 
57263ad1a0b9SPatrick Farrell   Not Collective
57273ad1a0b9SPatrick Farrell 
57283ad1a0b9SPatrick Farrell   Input Parameter:
57293ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
57303ad1a0b9SPatrick Farrell 
57313ad1a0b9SPatrick Farrell   Output Parameter:
57323ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
57333ad1a0b9SPatrick Farrell 
57343ad1a0b9SPatrick Farrell   Level: developer
57353ad1a0b9SPatrick Farrell 
5736db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()`
57373ad1a0b9SPatrick Farrell @*/
57383ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
57393ad1a0b9SPatrick Farrell {
57403ad1a0b9SPatrick Farrell   PetscFunctionBegin;
57413ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5742efd4aadfSBarry Smith   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
57433ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
57443ad1a0b9SPatrick Farrell }
57453ad1a0b9SPatrick Farrell 
5746c40d0f55SPeter Brune /*@
5747be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5748c40d0f55SPeter Brune 
5749c40d0f55SPeter Brune     Logically Collective on SNES
5750c40d0f55SPeter Brune 
5751c40d0f55SPeter Brune     Input Parameter:
5752c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5753c40d0f55SPeter Brune 
5754c40d0f55SPeter Brune     Output Parameter:
5755c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5756c40d0f55SPeter Brune .vb
57572d547940SBarry Smith       PC_LEFT - left preconditioning
57582d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5759c40d0f55SPeter Brune .ve
5760c40d0f55SPeter Brune 
5761c40d0f55SPeter Brune     Options Database Keys:
576267b8a455SSatish Balay .   -snes_npc_side <right,left> - nonlinear preconditioner side
5763c40d0f55SPeter Brune 
576495452b02SPatrick Sanan     Notes:
576595452b02SPatrick Sanan     SNESNRICHARDSON and SNESNCG only support left preconditioning.
57662d547940SBarry Smith 
5767c40d0f55SPeter Brune     Level: intermediate
5768c40d0f55SPeter Brune 
5769db781477SPatrick Sanan .seealso: `SNESGetNPCSide()`, `KSPSetPCSide()`
5770c40d0f55SPeter Brune @*/
5771be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5772c40d0f55SPeter Brune {
5773c40d0f55SPeter Brune   PetscFunctionBegin;
5774c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5775c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
5776b552625fSStefano Zampini   if (side == PC_SIDE_DEFAULT) side = PC_RIGHT;
577754c59aa7SJacob Faibussowitsch   PetscCheck((side == PC_LEFT) || (side == PC_RIGHT),PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Only PC_LEFT and PC_RIGHT are supported");
5778efd4aadfSBarry Smith   snes->npcside = side;
5779c40d0f55SPeter Brune   PetscFunctionReturn(0);
5780c40d0f55SPeter Brune }
5781c40d0f55SPeter Brune 
5782c40d0f55SPeter Brune /*@
5783be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5784c40d0f55SPeter Brune 
5785c40d0f55SPeter Brune     Not Collective
5786c40d0f55SPeter Brune 
5787c40d0f55SPeter Brune     Input Parameter:
5788c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5789c40d0f55SPeter Brune 
5790c40d0f55SPeter Brune     Output Parameter:
5791c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5792c40d0f55SPeter Brune .vb
57932d547940SBarry Smith       PC_LEFT - left preconditioning
57942d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5795c40d0f55SPeter Brune .ve
5796c40d0f55SPeter Brune 
5797c40d0f55SPeter Brune     Level: intermediate
5798c40d0f55SPeter Brune 
5799db781477SPatrick Sanan .seealso: `SNESSetNPCSide()`, `KSPGetPCSide()`
5800c40d0f55SPeter Brune @*/
5801be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5802c40d0f55SPeter Brune {
5803c40d0f55SPeter Brune   PetscFunctionBegin;
5804c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5805c40d0f55SPeter Brune   PetscValidPointer(side,2);
5806efd4aadfSBarry Smith   *side = snes->npcside;
5807c40d0f55SPeter Brune   PetscFunctionReturn(0);
5808c40d0f55SPeter Brune }
5809c40d0f55SPeter Brune 
58109e764e56SPeter Brune /*@
58117601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
58129e764e56SPeter Brune 
58139e764e56SPeter Brune   Collective on SNES
58149e764e56SPeter Brune 
58159e764e56SPeter Brune   Input Parameters:
58169e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
58179e764e56SPeter Brune - linesearch   - the linesearch object
58189e764e56SPeter Brune 
58199e764e56SPeter Brune   Notes:
58207601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
58219e764e56SPeter Brune   to configure it using the API).
58229e764e56SPeter Brune 
58239e764e56SPeter Brune   Level: developer
58249e764e56SPeter Brune 
5825db781477SPatrick Sanan .seealso: `SNESGetLineSearch()`
58269e764e56SPeter Brune @*/
58277601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
58289e764e56SPeter Brune {
58299e764e56SPeter Brune   PetscFunctionBegin;
58309e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5831f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
58329e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
58339566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject) linesearch));
58349566063dSJacob Faibussowitsch   PetscCall(SNESLineSearchDestroy(&snes->linesearch));
5835f5af7f23SKarl Rupp 
58369e764e56SPeter Brune   snes->linesearch = linesearch;
5837f5af7f23SKarl Rupp 
58389566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch));
58399e764e56SPeter Brune   PetscFunctionReturn(0);
58409e764e56SPeter Brune }
58419e764e56SPeter Brune 
5842a34ceb2aSJed Brown /*@
58437601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
58448141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
58459e764e56SPeter Brune 
58469e764e56SPeter Brune   Not Collective
58479e764e56SPeter Brune 
58489e764e56SPeter Brune   Input Parameter:
58499e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
58509e764e56SPeter Brune 
58519e764e56SPeter Brune   Output Parameter:
58529e764e56SPeter Brune . linesearch - linesearch context
58539e764e56SPeter Brune 
5854162e0bf5SPeter Brune   Level: beginner
58559e764e56SPeter Brune 
5856db781477SPatrick Sanan .seealso: `SNESSetLineSearch()`, `SNESLineSearchCreate()`
58579e764e56SPeter Brune @*/
58587601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
58599e764e56SPeter Brune {
58609e764e56SPeter Brune   const char     *optionsprefix;
58619e764e56SPeter Brune 
58629e764e56SPeter Brune   PetscFunctionBegin;
58639e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
58649e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
58659e764e56SPeter Brune   if (!snes->linesearch) {
58669566063dSJacob Faibussowitsch     PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix));
58679566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch));
58689566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes));
58699566063dSJacob Faibussowitsch     PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix));
58709566063dSJacob Faibussowitsch     PetscCall(PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1));
58719566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch));
58729e764e56SPeter Brune   }
58739e764e56SPeter Brune   *linesearch = snes->linesearch;
58749e764e56SPeter Brune   PetscFunctionReturn(0);
58759e764e56SPeter Brune }
5876