xref: /petsc/src/snes/interface/snes.c (revision 99c90e1218fd953acf7c03ffb7f9fa28ff0cd2be)
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:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
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 
33e113a28aSBarry Smith .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 
57e113a28aSBarry Smith .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 
794fc747eaSLawrence Mitchell .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 
1024fc747eaSLawrence Mitchell .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 
123bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
1244936397dSBarry Smith @*/
1257087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1264936397dSBarry Smith {
1274936397dSBarry Smith   PetscFunctionBegin;
1280700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
129422a814eSBarry Smith   if (snes->errorifnotconverged) SETERRQ(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 
14407b62357SFande Kong .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);
15007b62357SFande Kong   if (snes->errorifnotconverged) SETERRQ(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 
1678383d7d7SFande Kong .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 
1908383d7d7SFande Kong .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 
214bf388a1fSBarry Smith .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 
23807b62357SFande Kong .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 
27355849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
27455849f57SBarry Smith @*/
2752d53ad75SBarry Smith PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
27655849f57SBarry Smith {
27755849f57SBarry Smith   PetscErrorCode ierr;
27855849f57SBarry Smith   PetscBool      isbinary;
279060da220SMatthew G. Knepley   PetscInt       classid;
28055849f57SBarry Smith   char           type[256];
28155849f57SBarry Smith   KSP            ksp;
2822d53ad75SBarry Smith   DM             dm;
2832d53ad75SBarry Smith   DMSNES         dmsnes;
28455849f57SBarry Smith 
28555849f57SBarry Smith   PetscFunctionBegin;
2862d53ad75SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
28755849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
28855849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
28955849f57SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
29055849f57SBarry Smith 
291060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
292ce94432eSBarry Smith   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
293060da220SMatthew G. Knepley   ierr = PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR);CHKERRQ(ierr);
2942d53ad75SBarry Smith   ierr = SNESSetType(snes, type);CHKERRQ(ierr);
2952d53ad75SBarry Smith   if (snes->ops->load) {
2962d53ad75SBarry Smith     ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr);
297f2c2a1b9SBarry Smith   }
2982d53ad75SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2992d53ad75SBarry Smith   ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr);
3002d53ad75SBarry Smith   ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr);
3012d53ad75SBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
30255849f57SBarry Smith   ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr);
30355849f57SBarry Smith   PetscFunctionReturn(0);
30455849f57SBarry Smith }
3056a388c36SPeter Brune 
3069804daf3SBarry Smith #include <petscdraw.h>
307e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
308e04113cfSBarry Smith #include <petscviewersaws.h>
309bfb97211SBarry Smith #endif
3108404b7f3SBarry Smith 
311fe2efc57SMark /*@C
312fe2efc57SMark    SNESViewFromOptions - View from Options
313fe2efc57SMark 
314fe2efc57SMark    Collective on SNES
315fe2efc57SMark 
316fe2efc57SMark    Input Parameters:
317fe2efc57SMark +  A - the application ordering context
318736c3998SJose E. Roman .  obj - Optional object
319736c3998SJose E. Roman -  name - command line option
320fe2efc57SMark 
321fe2efc57SMark    Level: intermediate
322fe2efc57SMark .seealso:  SNES, SNESView, PetscObjectViewFromOptions(), SNESCreate()
323fe2efc57SMark @*/
324fe2efc57SMark PetscErrorCode  SNESViewFromOptions(SNES A,PetscObject obj,const char name[])
325fe2efc57SMark {
326fe2efc57SMark   PetscErrorCode ierr;
327fe2efc57SMark 
328fe2efc57SMark   PetscFunctionBegin;
329fe2efc57SMark   PetscValidHeaderSpecific(A,SNES_CLASSID,1);
330fe2efc57SMark   ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr);
331fe2efc57SMark   PetscFunctionReturn(0);
332fe2efc57SMark }
333fe2efc57SMark 
334789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*);
335789d8953SBarry Smith 
3367e2c5f70SBarry Smith /*@C
3379b94acceSBarry Smith    SNESView - Prints the SNES data structure.
3389b94acceSBarry Smith 
3394c49b128SBarry Smith    Collective on SNES
340fee21e36SBarry Smith 
341c7afd0dbSLois Curfman McInnes    Input Parameters:
342c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
343c7afd0dbSLois Curfman McInnes -  viewer - visualization context
344c7afd0dbSLois Curfman McInnes 
3459b94acceSBarry Smith    Options Database Key:
346c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
3479b94acceSBarry Smith 
3489b94acceSBarry Smith    Notes:
3499b94acceSBarry Smith    The available visualization contexts include
350b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
351b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
352c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
353c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
354c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
3559b94acceSBarry Smith 
3563e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
357b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
3589b94acceSBarry Smith 
359595c91d4SBarry Smith   In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer).
360595c91d4SBarry Smith 
36136851e7fSLois Curfman McInnes    Level: beginner
36236851e7fSLois Curfman McInnes 
363b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
3649b94acceSBarry Smith @*/
3657087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
3669b94acceSBarry Smith {
367fa9f3622SBarry Smith   SNESKSPEW      *kctx;
368dfbe8321SBarry Smith   PetscErrorCode ierr;
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) {
380ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
3813050cee2SBarry Smith   }
3820700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
383c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
38474679c65SBarry Smith 
385251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
386251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
38755849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
38872a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
389e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
390536b137fSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
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 
399dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr);
400fce1e034SJed Brown     if (!snes->setupcalled) {
401fce1e034SJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr);
402fce1e034SJed Brown     }
403e7788613SBarry Smith     if (snes->ops->view) {
404b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
405e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
406b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
4070ef38995SBarry Smith     }
40877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
40957622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr);
410efd4aadfSBarry Smith     if (snes->usesksp) {
41177431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
412efd4aadfSBarry Smith     }
41377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
414dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
415dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
41617fe4bdfSPeter Brune     if (snes->gridsequence) {
41717fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
41817fe4bdfSPeter Brune     }
4199b94acceSBarry Smith     if (snes->ksp_ewconv) {
420fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
4219b94acceSBarry Smith       if (kctx) {
42277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
42357622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold);CHKERRQ(ierr);
42457622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
4259b94acceSBarry Smith       }
4269b94acceSBarry Smith     }
427eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
428eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
429eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
430eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
431eb1f6c34SBarry Smith     }
432eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
433eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
434eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
43542f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
436eb1f6c34SBarry Smith     }
4378404b7f3SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4388404b7f3SBarry Smith     ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr);
439789d8953SBarry Smith     if (snes->mf_operator) {
440789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing\n");CHKERRQ(ierr);
441789d8953SBarry Smith       pre  = "Preconditioning ";
442789d8953SBarry Smith     }
4438404b7f3SBarry Smith     if (cJ == SNESComputeJacobianDefault) {
444789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences one column at a time\n",pre);CHKERRQ(ierr);
4458404b7f3SBarry Smith     } else if (cJ == SNESComputeJacobianDefaultColor) {
446789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences with coloring\n",pre);CHKERRQ(ierr);
447789d8953SBarry Smith     /* it slightly breaks data encapsulation for access the DMDA information directly */
448789d8953SBarry Smith     } else if (cJ == SNESComputeJacobian_DMDA) {
449789d8953SBarry Smith       MatFDColoring fdcoloring;
450789d8953SBarry Smith       ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr);
451789d8953SBarry Smith       if (fdcoloring) {
452789d8953SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using colored finite differences on a DMDA\n",pre);CHKERRQ(ierr);
453789d8953SBarry Smith       } else {
454789d8953SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using a DMDA local Jacobian\n",pre);CHKERRQ(ierr);
455789d8953SBarry Smith       }
456789d8953SBarry Smith     } else if (snes->mf) {
457789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing, no explict Jacobian\n");CHKERRQ(ierr);
4588404b7f3SBarry Smith     }
4590f5bd95cSBarry Smith   } else if (isstring) {
460317d6ea6SBarry Smith     const char *type;
461454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
46236a9e3b9SBarry Smith     ierr = PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type);CHKERRQ(ierr);
46336a9e3b9SBarry Smith     if (snes->ops->view) {ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);}
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 
47055849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
471ffc4695bSBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
47255849f57SBarry Smith     if (!rank) {
473f253e43cSLisandro Dalcin       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
47489d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
475f253e43cSLisandro Dalcin       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR);CHKERRQ(ierr);
47655849f57SBarry Smith     }
47755849f57SBarry Smith     if (snes->ops->view) {
47855849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
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 
48572a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
48672a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
487a126751eSBarry Smith     ierr   = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr);
488a126751eSBarry Smith     ierr   = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr);
48951fa3d41SBarry Smith     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
49089fd9fafSBarry Smith     bottom = y - h;
49172a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
492c4646bacSPeter Brune     if (snes->ops->view) {
493c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
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 
5002657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
501ffc4695bSBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr);
502d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
503d45a07a7SBarry Smith       char       dir[1024];
504d45a07a7SBarry Smith 
505e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
5062657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
5072657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
508bfb97211SBarry Smith       if (!snes->conv_hist) {
509a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
510bfb97211SBarry Smith       }
5112657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
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) {
5177601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
51885928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
51972a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
52085928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
52119bcc07fSBarry Smith   }
522efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
52385928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
524efd4aadfSBarry Smith     ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr);
52585928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5264a0c5b0cSMatthew G Knepley   }
5272d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
5282d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
5292d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
5302d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5312c155ee1SBarry Smith   if (snes->usesksp) {
5322c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
53385928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
53494b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
53585928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5362c155ee1SBarry Smith   }
53772a02f06SBarry Smith   if (isdraw) {
53872a02f06SBarry Smith     PetscDraw draw;
53972a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
54072a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
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 
56376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
56476b2cf59SMatthew Knepley @*/
5657087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
56676b2cf59SMatthew Knepley {
56776b2cf59SMatthew Knepley   PetscFunctionBegin;
568f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(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;
578aa3661deSLisandro Dalcin   PetscErrorCode ierr;
579895c21f2SBarry Smith   MatNullSpace   nullsp;
580aa3661deSLisandro Dalcin 
581aa3661deSLisandro Dalcin   PetscFunctionBegin;
5820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
583aa3661deSLisandro Dalcin 
58498613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
58598613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
5862a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
58798613b67SLisandro Dalcin   }
58898613b67SLisandro Dalcin 
589aa3661deSLisandro Dalcin   if (version == 1) {
590aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
59198613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5929c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
593aa3661deSLisandro Dalcin   } else if (version == 2) {
594e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(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)
596aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
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) {
604895c21f2SBarry Smith     ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr);
605895c21f2SBarry Smith     if (nullsp) {
606895c21f2SBarry Smith       ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr);
607895c21f2SBarry Smith     }
608895c21f2SBarry Smith   }
609895c21f2SBarry Smith 
610aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
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. */
6159e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);
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. */
619efd4aadfSBarry Smith     if ((snes->npcside== PC_LEFT) && snes->npc) {
6209e5d0892SLisandro Dalcin       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);}
621172a4300SPeter Brune     } else {
622789d8953SBarry Smith       KSP       ksp;
623789d8953SBarry Smith       PC        pc;
624789d8953SBarry Smith       PetscBool match;
625789d8953SBarry Smith 
6269e5d0892SLisandro Dalcin       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr);
627aa3661deSLisandro Dalcin       /* Force no preconditioner */
628aa3661deSLisandro Dalcin       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
629aa3661deSLisandro Dalcin       ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
630251f4c67SDmitry Karpeev       ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
631aa3661deSLisandro Dalcin       if (!match) {
632aa3661deSLisandro Dalcin         ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
633aa3661deSLisandro Dalcin         ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
634aa3661deSLisandro Dalcin       }
635aa3661deSLisandro Dalcin     }
636789d8953SBarry Smith   }
6376bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
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;
644dfe15315SJed Brown   PetscErrorCode ierr;
6450298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
646dfe15315SJed Brown 
647dfe15315SJed Brown   PetscFunctionBegin;
64816ebb321SJed Brown   if (PetscLogPrintInfo) {
64916ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
65016ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
65116ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
65216ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
65316ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
65416ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
65516ebb321SJed Brown   }
656dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
657dfe15315SJed Brown   else {
658dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
659dfe15315SJed Brown     Xfine = Xfine_named;
660dfe15315SJed Brown   }
661dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
662907f5c5aSLawrence Mitchell   if (Inject) {
663907f5c5aSLawrence Mitchell     ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr);
664907f5c5aSLawrence Mitchell   } else {
665dfe15315SJed Brown     ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
666dfe15315SJed Brown     ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
667907f5c5aSLawrence Mitchell   }
668dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
669dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
670dfe15315SJed Brown   PetscFunctionReturn(0);
671dfe15315SJed Brown }
672dfe15315SJed Brown 
67316ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
67416ebb321SJed Brown {
67516ebb321SJed Brown   PetscErrorCode ierr;
67616ebb321SJed Brown 
67716ebb321SJed Brown   PetscFunctionBegin;
67816ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
67916ebb321SJed Brown   PetscFunctionReturn(0);
68016ebb321SJed Brown }
68116ebb321SJed Brown 
682a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
683a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
68423ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
685caa4e7f2SJed Brown {
686caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
687caa4e7f2SJed Brown   PetscErrorCode ierr;
6880298fd71SBarry Smith   Vec            X,Xnamed = NULL;
689dfe15315SJed Brown   DM             dmsave;
6904e269d77SPeter Brune   void           *ctxsave;
69125ce1634SJed Brown   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;
692caa4e7f2SJed Brown 
693caa4e7f2SJed Brown   PetscFunctionBegin;
694dfe15315SJed Brown   dmsave = snes->dm;
695dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
696dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
697dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
698dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
699dfe15315SJed Brown     X    = Xnamed;
7000298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
7014e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
7028d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
7039e5d0892SLisandro Dalcin       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
704dfe15315SJed Brown     }
7054e269d77SPeter Brune   }
7064dde8bb0SMatthew G. Knepley   /* Make sure KSP DM has the Jacobian computation routine */
7074dde8bb0SMatthew G. Knepley   {
7084dde8bb0SMatthew G. Knepley     DMSNES sdm;
7094e269d77SPeter Brune 
7104dde8bb0SMatthew G. Knepley     ierr = DMGetDMSNES(snes->dm, &sdm);CHKERRQ(ierr);
7114dde8bb0SMatthew G. Knepley     if (!sdm->ops->computejacobian) {
7124dde8bb0SMatthew G. Knepley       ierr = DMCopyDMSNES(dmsave, snes->dm);CHKERRQ(ierr);
7134dde8bb0SMatthew G. Knepley     }
7144dde8bb0SMatthew G. Knepley   }
7152b93b426SMatthew G. Knepley   /* Compute the operators */
716d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
7172b93b426SMatthew G. Knepley   /* Put the previous context back */
7188d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
7190298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
7204e269d77SPeter Brune   }
7214e269d77SPeter Brune 
7222b93b426SMatthew G. Knepley   if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);}
723dfe15315SJed Brown   snes->dm = dmsave;
724caa4e7f2SJed Brown   PetscFunctionReturn(0);
725caa4e7f2SJed Brown }
726caa4e7f2SJed Brown 
7276cab3a1bSJed Brown /*@
7286cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
7296cab3a1bSJed Brown 
7306cab3a1bSJed Brown    Collective
7316cab3a1bSJed Brown 
7326cab3a1bSJed Brown    Input Arguments:
7336cab3a1bSJed Brown .  snes - snes to configure
7346cab3a1bSJed Brown 
7356cab3a1bSJed Brown    Level: developer
7366cab3a1bSJed Brown 
7376cab3a1bSJed Brown .seealso: SNESSetUp()
7386cab3a1bSJed Brown @*/
7396cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
7406cab3a1bSJed Brown {
7416cab3a1bSJed Brown   PetscErrorCode ierr;
7426cab3a1bSJed Brown   DM             dm;
743942e3340SBarry Smith   DMSNES         sdm;
7446cab3a1bSJed Brown 
7456cab3a1bSJed Brown   PetscFunctionBegin;
7466cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
747942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
74858b371f3SBarry Smith   if (!snes->jacobian && snes->mf) {
7496cab3a1bSJed Brown     Mat  J;
7506cab3a1bSJed Brown     void *functx;
7516cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
7526cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
7536cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
7540298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
7559e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,NULL,NULL);CHKERRQ(ierr);
7566cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
757caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
7586cab3a1bSJed Brown     Mat J,B;
7596cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
7606cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
7616cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
762b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
76306f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
7640298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
7656cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
7666cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
767caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
7681ba9b98eSMatthew G. Knepley     PetscDS   prob;
7696cab3a1bSJed Brown     Mat       J, B;
7701ba9b98eSMatthew G. Knepley     PetscBool hasPrec   = PETSC_FALSE;
7711ba9b98eSMatthew G. Knepley 
7726cab3a1bSJed Brown     J    = snes->jacobian;
7731ba9b98eSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
7741ba9b98eSMatthew G. Knepley     if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);}
775ec9a985fSMatthew G. Knepley     if (J)            {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);}
776ec9a985fSMatthew G. Knepley     else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);}
777b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr);
7780298fd71SBarry Smith     ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr);
7791ba9b98eSMatthew G. Knepley     ierr = MatDestroy(&J);CHKERRQ(ierr);
7806cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
7816cab3a1bSJed Brown   }
782caa4e7f2SJed Brown   {
783caa4e7f2SJed Brown     KSP ksp;
784caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
785caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
78616ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
787caa4e7f2SJed Brown   }
7886cab3a1bSJed Brown   PetscFunctionReturn(0);
7896cab3a1bSJed Brown }
7906cab3a1bSJed Brown 
791fde5950dSBarry Smith /*@C
792fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
793fde5950dSBarry Smith 
794fde5950dSBarry Smith    Collective on SNES
795fde5950dSBarry Smith 
796fde5950dSBarry Smith    Input Parameters:
797fde5950dSBarry Smith +  snes - SNES object you wish to monitor
798fde5950dSBarry Smith .  name - the monitor type one is seeking
799fde5950dSBarry Smith .  help - message indicating what monitoring is done
800fde5950dSBarry Smith .  manual - manual page for the monitor
801fde5950dSBarry Smith .  monitor - the monitor function
802fde5950dSBarry 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
803fde5950dSBarry Smith 
804fde5950dSBarry Smith    Level: developer
805fde5950dSBarry Smith 
806fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
807fde5950dSBarry Smith           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
808fde5950dSBarry Smith           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
809fde5950dSBarry Smith           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
810fde5950dSBarry Smith           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
811fde5950dSBarry Smith           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
812fde5950dSBarry Smith           PetscOptionsFList(), PetscOptionsEList()
813fde5950dSBarry Smith @*/
814d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
815fde5950dSBarry Smith {
816fde5950dSBarry Smith   PetscErrorCode    ierr;
817fde5950dSBarry Smith   PetscViewer       viewer;
818fde5950dSBarry Smith   PetscViewerFormat format;
819fde5950dSBarry Smith   PetscBool         flg;
820fde5950dSBarry Smith 
821fde5950dSBarry Smith   PetscFunctionBegin;
82216413a6aSBarry Smith   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
823fde5950dSBarry Smith   if (flg) {
824d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
825d43b4f6eSBarry Smith     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
826d43b4f6eSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
827fde5950dSBarry Smith     if (monitorsetup) {
828d43b4f6eSBarry Smith       ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr);
829fde5950dSBarry Smith     }
830d43b4f6eSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
831fde5950dSBarry Smith   }
832fde5950dSBarry Smith   PetscFunctionReturn(0);
833fde5950dSBarry Smith }
834fde5950dSBarry Smith 
8359b94acceSBarry Smith /*@
83694b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
8379b94acceSBarry Smith 
838c7afd0dbSLois Curfman McInnes    Collective on SNES
839c7afd0dbSLois Curfman McInnes 
8409b94acceSBarry Smith    Input Parameter:
8419b94acceSBarry Smith .  snes - the SNES context
8429b94acceSBarry Smith 
84336851e7fSLois Curfman McInnes    Options Database Keys:
844722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
84582738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
84682738288SBarry Smith                 of the change in the solution between steps
84770441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
848b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
849e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
850be5caee7SBarry Smith .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
851b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
852b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
8534839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
854ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
855a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
8563d5a8a6aSBarry Smith .  -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve()
857e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
8583d5a8a6aSBarry Smith .  -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve()
859b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
8602492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
86182738288SBarry Smith                                solver; hence iterations will continue until max_it
8621fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
86382738288SBarry Smith                                of convergence test
864fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
865fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
866fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
867fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
8684619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
869459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
870e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
871e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
8725968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
873b5badacbSBarry Smith .  -snes_converged_reason - print the reason for convergence/divergence after each solve
874e62ac41dSBarry Smith .  -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner
875e62ac41dSBarry 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.
876e62ac41dSBarry 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.
87782738288SBarry Smith 
87882738288SBarry Smith     Options Database for Eisenstat-Walker method:
879fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
8804b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
88136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
88236851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
88336851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
88436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
88536851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
88636851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
88782738288SBarry Smith 
88811ca99fdSLois Curfman McInnes    Notes:
889ec5066bdSBarry Smith    To see all options, run your program with the -help option or consult the users manual
890ec5066bdSBarry Smith 
891ec5066bdSBarry Smith    Notes:
892ec5066bdSBarry Smith       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly with
893ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
89483e2fdc7SBarry Smith 
89536851e7fSLois Curfman McInnes    Level: beginner
89636851e7fSLois Curfman McInnes 
897ec5066bdSBarry Smith .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions(), SNES, SNESCreate()
8989b94acceSBarry Smith @*/
8997087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
9009b94acceSBarry Smith {
9018afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
902d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
90304d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
904649ef022SMatthew Knepley   const char     *convtests[] = {"default","skip","correct_pressure"};
90585385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
906e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
90785385478SLisandro Dalcin   PetscErrorCode ierr;
908c40d0f55SPeter Brune   PCSide         pcside;
909a64e098fSPeter Brune   const char     *optionsprefix;
9109b94acceSBarry Smith 
9113a40ed3dSBarry Smith   PetscFunctionBegin;
9120700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9130f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
9143194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
915639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
916a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
917d64ed03dSBarry Smith   if (flg) {
918186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
9197adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
920186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
921d64ed03dSBarry Smith   }
92294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
92394ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
924186905e3SBarry Smith 
92594ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
926e4d06f11SPatrick Farrell   ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr);
9270298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
9280298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
9290298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
9300298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
9310298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
9320d6f27a8SBarry Smith   ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr);
933b351a90bSFande Kong   ierr = PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL);CHKERRQ(ierr);
93485385478SLisandro Dalcin 
935a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
936a8054027SBarry Smith   if (flg) {
9373d5a8a6aSBarry Smith     if (lag == -1) SETERRQ(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");
938a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
939a8054027SBarry Smith   }
9409590daa0SBarry Smith   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
94137ec4e1aSPeter Brune   if (flg) {
94237ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
94337ec4e1aSPeter Brune   }
944e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
945e35cf81dSBarry Smith   if (flg) {
9463d5a8a6aSBarry Smith     if (lag == -1) SETERRQ(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");
947e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
948e35cf81dSBarry Smith   }
9499590daa0SBarry Smith   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
95037ec4e1aSPeter Brune   if (flg) {
95137ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
95237ec4e1aSPeter Brune   }
95337ec4e1aSPeter Brune 
954efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
955efd51863SBarry Smith   if (flg) {
956efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
957efd51863SBarry Smith   }
958a8054027SBarry Smith 
959649ef022SMatthew Knepley   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg);CHKERRQ(ierr);
96085385478SLisandro Dalcin   if (flg) {
96185385478SLisandro Dalcin     switch (indx) {
9628d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
963e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr); break;
964649ef022SMatthew Knepley     case 2: ierr = SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL);CHKERRQ(ierr); break;
96585385478SLisandro Dalcin     }
96685385478SLisandro Dalcin   }
96785385478SLisandro Dalcin 
968365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
969365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
970fdacfa88SPeter Brune 
97147073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
97247073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
973186905e3SBarry Smith 
97485385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
97585385478SLisandro Dalcin 
9760298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
977186905e3SBarry Smith 
97894ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
97994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
98094ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
98194ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
98294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
98394ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
98494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
985186905e3SBarry Smith 
98690d69ab7SBarry Smith   flg  = PETSC_FALSE;
9878afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
9888afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
989eabae89aSBarry Smith 
990fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr);
991fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr);
992fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr);
993eabae89aSBarry Smith 
994fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr);
995fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr);
996fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr);
997fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
998fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr);
999fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr);
1000fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr);
10012db13446SMatthew G. Knepley 
1002589a23caSBarry Smith   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr);
10035180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
10045180491cSLisandro Dalcin 
100590d69ab7SBarry Smith   flg  = PETSC_FALSE;
10060298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
1007459f5d12SBarry Smith   if (flg) {
1008459f5d12SBarry Smith     PetscViewer ctx;
1009e24b481bSBarry Smith 
10106ba87a44SLisandro Dalcin     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
1011459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
1012459f5d12SBarry Smith   }
10132e7541e6SPeter Brune 
101490d69ab7SBarry Smith   flg  = PETSC_FALSE;
1015c4421ceaSFande Kong   ierr = PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set);CHKERRQ(ierr);
1016c4421ceaSFande Kong   if (set && flg) {ierr = SNESConvergedReasonViewCancel(snes);CHKERRQ(ierr);}
1017c4421ceaSFande Kong 
1018c4421ceaSFande Kong   flg  = PETSC_FALSE;
10198d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
10204b27c08aSLois Curfman McInnes   if (flg) {
10216cab3a1bSJed Brown     void    *functx;
1022b1f624c7SBarry Smith     DM      dm;
1023b1f624c7SBarry Smith     DMSNES  sdm;
1024b1f624c7SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1025b1f624c7SBarry Smith     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
1026b1f624c7SBarry Smith     sdm->jacobianctx = NULL;
10270298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
10288d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
1029ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
10309b94acceSBarry Smith   }
1031639f9d9dSBarry Smith 
103244848bc4SPeter Brune   flg  = PETSC_FALSE;
10338d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
103497584545SPeter Brune   if (flg) {
10358d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
103697584545SPeter Brune   }
103797584545SPeter Brune 
103897584545SPeter Brune   flg  = PETSC_FALSE;
10398d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
104044848bc4SPeter Brune   if (flg) {
1041c52e227fSPeter Brune     DM             dm;
1042c52e227fSPeter Brune     DMSNES         sdm;
1043c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1044aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
1045aace71b7SPeter Brune     sdm->jacobianctx = NULL;
10469e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
104744848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
104844848bc4SPeter Brune   }
104944848bc4SPeter Brune 
1050aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
1051f871313dSBarry Smith   ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr);
1052d8f46077SPeter Brune   if (flg && snes->mf_operator) {
1053a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
1054d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
1055a8248277SBarry Smith   }
1056aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
1057f871313dSBarry Smith   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
1058d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
10599e5d0892SLisandro Dalcin   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL);CHKERRQ(ierr);
1060d28543b3SPeter Brune 
1061c40d0f55SPeter Brune   flg  = PETSC_FALSE;
1062be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
1063be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
1064be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
1065c40d0f55SPeter Brune 
1066e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
10678a70d858SHong Zhang   /*
10688a70d858SHong Zhang     Publish convergence information using SAWs
10698a70d858SHong Zhang   */
10708a70d858SHong Zhang   flg  = PETSC_FALSE;
10718a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
10728a70d858SHong Zhang   if (flg) {
10738a70d858SHong Zhang     void *ctx;
10748a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
10758a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
10768a70d858SHong Zhang   }
10778a70d858SHong Zhang #endif
10788a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
1079b90c6cbeSBarry Smith   {
1080b90c6cbeSBarry Smith   PetscBool set;
1081b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
10828a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
1083b90c6cbeSBarry Smith   if (set) {
1084e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
1085b90c6cbeSBarry Smith   }
1086b90c6cbeSBarry Smith   }
1087b90c6cbeSBarry Smith #endif
1088b90c6cbeSBarry Smith 
108976b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
109076b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
109176b2cf59SMatthew Knepley   }
109276b2cf59SMatthew Knepley 
1093e7788613SBarry Smith   if (snes->ops->setfromoptions) {
1094e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
1095639f9d9dSBarry Smith   }
10965d973c19SBarry Smith 
10975d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
10980633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr);
1099b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
11004bbc92c1SBarry Smith 
1101d8d34be6SBarry Smith   if (snes->linesearch) {
11027601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
1103f1c6b773SPeter Brune     ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
1104d8d34be6SBarry Smith   }
11059e764e56SPeter Brune 
11066aa5e7e9SBarry Smith   if (snes->usesksp) {
11076991f827SBarry Smith     if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
11086991f827SBarry Smith     ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
11096991f827SBarry Smith     ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
11106aa5e7e9SBarry Smith   }
11116991f827SBarry Smith 
1112b5badacbSBarry Smith   /* if user has set the SNES NPC type via options database, create it. */
111351e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
1114c5929fdfSBarry Smith   ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
1115efd4aadfSBarry Smith   if (pcset && (!snes->npc)) {
1116efd4aadfSBarry Smith     ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr);
111751e86f29SPeter Brune   }
1118b5badacbSBarry Smith   if (snes->npc) {
1119b5badacbSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
1120b5badacbSBarry Smith   }
1121b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled++;
1122b3cd9a81SMatthew G. Knepley   PetscFunctionReturn(0);
1123b3cd9a81SMatthew G. Knepley }
1124b3cd9a81SMatthew G. Knepley 
1125b3cd9a81SMatthew G. Knepley /*@
1126b3cd9a81SMatthew G. Knepley    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options
1127b3cd9a81SMatthew G. Knepley 
1128b3cd9a81SMatthew G. Knepley    Collective on SNES
1129b3cd9a81SMatthew G. Knepley 
1130b3cd9a81SMatthew G. Knepley    Input Parameter:
1131b3cd9a81SMatthew G. Knepley .  snes - the SNES context
1132b3cd9a81SMatthew G. Knepley 
1133b3cd9a81SMatthew G. Knepley    Level: beginner
1134b3cd9a81SMatthew G. Knepley 
1135b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix()
1136b3cd9a81SMatthew G. Knepley @*/
1137b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes)
1138b3cd9a81SMatthew G. Knepley {
1139b3cd9a81SMatthew G. Knepley   PetscErrorCode ierr;
1140b3cd9a81SMatthew G. Knepley 
1141b3cd9a81SMatthew G. Knepley   PetscFunctionBegin;
1142b3cd9a81SMatthew G. Knepley   if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);}
11433a40ed3dSBarry Smith   PetscFunctionReturn(0);
11449b94acceSBarry Smith }
11459b94acceSBarry Smith 
1146bb9467b5SJed Brown /*@C
1147d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1148d25893d9SBarry Smith    the nonlinear solvers.
1149d25893d9SBarry Smith 
1150d25893d9SBarry Smith    Logically Collective on SNES
1151d25893d9SBarry Smith 
1152d25893d9SBarry Smith    Input Parameters:
1153d25893d9SBarry Smith +  snes - the SNES context
1154d25893d9SBarry Smith .  compute - function to compute the context
1155d25893d9SBarry Smith -  destroy - function to destroy the context
1156d25893d9SBarry Smith 
1157d25893d9SBarry Smith    Level: intermediate
1158d25893d9SBarry Smith 
1159bb9467b5SJed Brown    Notes:
1160bb9467b5SJed Brown    This function is currently not available from Fortran.
1161bb9467b5SJed Brown 
1162d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
1163d25893d9SBarry Smith @*/
1164d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
1165d25893d9SBarry Smith {
1166d25893d9SBarry Smith   PetscFunctionBegin;
1167d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1168d25893d9SBarry Smith   snes->ops->usercompute = compute;
1169d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
1170d25893d9SBarry Smith   PetscFunctionReturn(0);
1171d25893d9SBarry Smith }
1172a847f771SSatish Balay 
1173b07ff414SBarry Smith /*@
11749b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
11759b94acceSBarry Smith    the nonlinear solvers.
11769b94acceSBarry Smith 
11773f9fe445SBarry Smith    Logically Collective on SNES
1178fee21e36SBarry Smith 
1179c7afd0dbSLois Curfman McInnes    Input Parameters:
1180c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1181c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1182c7afd0dbSLois Curfman McInnes 
118336851e7fSLois Curfman McInnes    Level: intermediate
118436851e7fSLois Curfman McInnes 
118595452b02SPatrick Sanan    Fortran Notes:
118695452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1187daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1188daf670e6SBarry Smith 
1189ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
11909b94acceSBarry Smith @*/
11917087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
11929b94acceSBarry Smith {
11931b2093e4SBarry Smith   PetscErrorCode ierr;
1194b07ff414SBarry Smith   KSP            ksp;
11951b2093e4SBarry Smith 
11963a40ed3dSBarry Smith   PetscFunctionBegin;
11970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1198b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
1199b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
12009b94acceSBarry Smith   snes->user = usrP;
12013a40ed3dSBarry Smith   PetscFunctionReturn(0);
12029b94acceSBarry Smith }
120374679c65SBarry Smith 
1204b07ff414SBarry Smith /*@
12059b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
12069b94acceSBarry Smith    nonlinear solvers.
12079b94acceSBarry Smith 
1208c7afd0dbSLois Curfman McInnes    Not Collective
1209c7afd0dbSLois Curfman McInnes 
12109b94acceSBarry Smith    Input Parameter:
12119b94acceSBarry Smith .  snes - SNES context
12129b94acceSBarry Smith 
12139b94acceSBarry Smith    Output Parameter:
12149b94acceSBarry Smith .  usrP - user context
12159b94acceSBarry Smith 
121695452b02SPatrick Sanan    Fortran Notes:
121795452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1218daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1219daf670e6SBarry Smith 
122036851e7fSLois Curfman McInnes    Level: intermediate
122136851e7fSLois Curfman McInnes 
12229b94acceSBarry Smith .seealso: SNESSetApplicationContext()
12239b94acceSBarry Smith @*/
1224e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
12259b94acceSBarry Smith {
12263a40ed3dSBarry Smith   PetscFunctionBegin;
12270700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1228e71120c6SJed Brown   *(void**)usrP = snes->user;
12293a40ed3dSBarry Smith   PetscFunctionReturn(0);
12309b94acceSBarry Smith }
123174679c65SBarry Smith 
12329b94acceSBarry Smith /*@
1233ec5066bdSBarry Smith    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian.
12343565c898SBarry Smith 
12353565c898SBarry Smith    Collective on SNES
12363565c898SBarry Smith 
12373565c898SBarry Smith    Input Parameters:
12383565c898SBarry Smith +  snes - SNES context
12394ddffce6SLisandro Dalcin .  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
12404ddffce6SLisandro 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
12413565c898SBarry Smith 
12423565c898SBarry Smith    Options Database:
12433565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
1244ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator
1245ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences.
1246ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow)
12473565c898SBarry Smith 
12483565c898SBarry Smith    Level: intermediate
12493565c898SBarry Smith 
1250ec5066bdSBarry Smith    Notes:
1251ec5066bdSBarry Smith       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly with
1252ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
1253ec5066bdSBarry Smith 
1254ec5066bdSBarry Smith .seealso:   SNESGetUseMatrixFree(), MatCreateSNESMF(), SNESComputeJacobianDefaultColor()
12553565c898SBarry Smith @*/
12563565c898SBarry Smith PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
12573565c898SBarry Smith {
12583565c898SBarry Smith   PetscFunctionBegin;
12593565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
126088b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf_operator,2);
126188b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf,3);
12624ddffce6SLisandro Dalcin   snes->mf          = mf_operator ? PETSC_TRUE : mf;
12633565c898SBarry Smith   snes->mf_operator = mf_operator;
12643565c898SBarry Smith   PetscFunctionReturn(0);
12653565c898SBarry Smith }
12663565c898SBarry Smith 
12673565c898SBarry Smith /*@
1268ec5066bdSBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian.
12693565c898SBarry Smith 
12703565c898SBarry Smith    Collective on SNES
12713565c898SBarry Smith 
12723565c898SBarry Smith    Input Parameter:
12733565c898SBarry Smith .  snes - SNES context
12743565c898SBarry Smith 
12753565c898SBarry Smith    Output Parameters:
12764ddffce6SLisandro Dalcin +  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
12774ddffce6SLisandro 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
12783565c898SBarry Smith 
12793565c898SBarry Smith    Options Database:
12803565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
12813565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
12823565c898SBarry Smith 
12833565c898SBarry Smith    Level: intermediate
12843565c898SBarry Smith 
12853565c898SBarry Smith .seealso:   SNESSetUseMatrixFree(), MatCreateSNESMF()
12863565c898SBarry Smith @*/
12873565c898SBarry Smith PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
12883565c898SBarry Smith {
12893565c898SBarry Smith   PetscFunctionBegin;
12903565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12913565c898SBarry Smith   if (mf)          *mf          = snes->mf;
12923565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
12933565c898SBarry Smith   PetscFunctionReturn(0);
12943565c898SBarry Smith }
12953565c898SBarry Smith 
12963565c898SBarry Smith /*@
1297c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1298c8228a4eSBarry Smith    at this time.
12999b94acceSBarry Smith 
1300c7afd0dbSLois Curfman McInnes    Not Collective
1301c7afd0dbSLois Curfman McInnes 
13029b94acceSBarry Smith    Input Parameter:
13039b94acceSBarry Smith .  snes - SNES context
13049b94acceSBarry Smith 
13059b94acceSBarry Smith    Output Parameter:
13069b94acceSBarry Smith .  iter - iteration number
13079b94acceSBarry Smith 
1308c8228a4eSBarry Smith    Notes:
1309c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1310c8228a4eSBarry Smith 
1311c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
131208405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
131308405cd6SLois Curfman McInnes .vb
131408405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
131508405cd6SLois Curfman McInnes       if (!(it % 2)) {
131608405cd6SLois Curfman McInnes         [compute Jacobian here]
131708405cd6SLois Curfman McInnes       }
131808405cd6SLois Curfman McInnes .ve
1319c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
132008405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1321c8228a4eSBarry Smith 
1322c04deec6SBarry Smith    After the SNES solve is complete this will return the number of nonlinear iterations used.
1323c04deec6SBarry Smith 
132436851e7fSLois Curfman McInnes    Level: intermediate
132536851e7fSLois Curfman McInnes 
132671dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
13279b94acceSBarry Smith @*/
13287087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
13299b94acceSBarry Smith {
13303a40ed3dSBarry Smith   PetscFunctionBegin;
13310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13324482741eSBarry Smith   PetscValidIntPointer(iter,2);
13339b94acceSBarry Smith   *iter = snes->iter;
13343a40ed3dSBarry Smith   PetscFunctionReturn(0);
13359b94acceSBarry Smith }
133674679c65SBarry Smith 
1337360c497dSPeter Brune /*@
1338360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1339360c497dSPeter Brune 
1340360c497dSPeter Brune    Not Collective
1341360c497dSPeter Brune 
1342360c497dSPeter Brune    Input Parameter:
1343a2b725a8SWilliam Gropp +  snes - SNES context
1344a2b725a8SWilliam Gropp -  iter - iteration number
1345360c497dSPeter Brune 
1346360c497dSPeter Brune    Level: developer
1347360c497dSPeter Brune 
134871dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1349360c497dSPeter Brune @*/
1350360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1351360c497dSPeter Brune {
1352360c497dSPeter Brune   PetscErrorCode ierr;
1353360c497dSPeter Brune 
1354360c497dSPeter Brune   PetscFunctionBegin;
1355360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1356e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1357360c497dSPeter Brune   snes->iter = iter;
1358e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1359360c497dSPeter Brune   PetscFunctionReturn(0);
1360360c497dSPeter Brune }
1361360c497dSPeter Brune 
13629b94acceSBarry Smith /*@
1363b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
13649b94acceSBarry Smith    attempted by the nonlinear solver.
13659b94acceSBarry Smith 
1366c7afd0dbSLois Curfman McInnes    Not Collective
1367c7afd0dbSLois Curfman McInnes 
13689b94acceSBarry Smith    Input Parameter:
13699b94acceSBarry Smith .  snes - SNES context
13709b94acceSBarry Smith 
13719b94acceSBarry Smith    Output Parameter:
13729b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
13739b94acceSBarry Smith 
1374c96a6f78SLois Curfman McInnes    Notes:
1375c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1376c96a6f78SLois Curfman McInnes 
137736851e7fSLois Curfman McInnes    Level: intermediate
137836851e7fSLois Curfman McInnes 
1379e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
138058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
13819b94acceSBarry Smith @*/
13827087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
13839b94acceSBarry Smith {
13843a40ed3dSBarry Smith   PetscFunctionBegin;
13850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13864482741eSBarry Smith   PetscValidIntPointer(nfails,2);
138750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
138850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
138950ffb88aSMatthew Knepley }
139050ffb88aSMatthew Knepley 
139150ffb88aSMatthew Knepley /*@
1392b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
139350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
139450ffb88aSMatthew Knepley 
139550ffb88aSMatthew Knepley    Not Collective
139650ffb88aSMatthew Knepley 
139750ffb88aSMatthew Knepley    Input Parameters:
139850ffb88aSMatthew Knepley +  snes     - SNES context
139950ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
140050ffb88aSMatthew Knepley 
140150ffb88aSMatthew Knepley    Level: intermediate
140250ffb88aSMatthew Knepley 
1403e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
140458ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
140550ffb88aSMatthew Knepley @*/
14067087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
140750ffb88aSMatthew Knepley {
140850ffb88aSMatthew Knepley   PetscFunctionBegin;
14090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
141050ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
141150ffb88aSMatthew Knepley   PetscFunctionReturn(0);
141250ffb88aSMatthew Knepley }
141350ffb88aSMatthew Knepley 
141450ffb88aSMatthew Knepley /*@
1415b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
141650ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
141750ffb88aSMatthew Knepley 
141850ffb88aSMatthew Knepley    Not Collective
141950ffb88aSMatthew Knepley 
142050ffb88aSMatthew Knepley    Input Parameter:
142150ffb88aSMatthew Knepley .  snes     - SNES context
142250ffb88aSMatthew Knepley 
142350ffb88aSMatthew Knepley    Output Parameter:
142450ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
142550ffb88aSMatthew Knepley 
142650ffb88aSMatthew Knepley    Level: intermediate
142750ffb88aSMatthew Knepley 
1428e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
142958ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
143058ebbce7SBarry Smith 
143150ffb88aSMatthew Knepley @*/
14327087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
143350ffb88aSMatthew Knepley {
143450ffb88aSMatthew Knepley   PetscFunctionBegin;
14350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14364482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
143750ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
14383a40ed3dSBarry Smith   PetscFunctionReturn(0);
14399b94acceSBarry Smith }
1440a847f771SSatish Balay 
14412541af92SBarry Smith /*@
14422541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
14432541af92SBarry Smith      done by SNES.
14442541af92SBarry Smith 
14452541af92SBarry Smith    Not Collective
14462541af92SBarry Smith 
14472541af92SBarry Smith    Input Parameter:
14482541af92SBarry Smith .  snes     - SNES context
14492541af92SBarry Smith 
14502541af92SBarry Smith    Output Parameter:
14512541af92SBarry Smith .  nfuncs - number of evaluations
14522541af92SBarry Smith 
14532541af92SBarry Smith    Level: intermediate
14542541af92SBarry Smith 
145595452b02SPatrick Sanan    Notes:
145695452b02SPatrick Sanan     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1457971e163fSPeter Brune 
1458971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
14592541af92SBarry Smith @*/
14607087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
14612541af92SBarry Smith {
14622541af92SBarry Smith   PetscFunctionBegin;
14630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14642541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
14652541af92SBarry Smith   *nfuncs = snes->nfuncs;
14662541af92SBarry Smith   PetscFunctionReturn(0);
14672541af92SBarry Smith }
14682541af92SBarry Smith 
14693d4c4710SBarry Smith /*@
14703d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
14713d4c4710SBarry Smith    linear solvers.
14723d4c4710SBarry Smith 
14733d4c4710SBarry Smith    Not Collective
14743d4c4710SBarry Smith 
14753d4c4710SBarry Smith    Input Parameter:
14763d4c4710SBarry Smith .  snes - SNES context
14773d4c4710SBarry Smith 
14783d4c4710SBarry Smith    Output Parameter:
14793d4c4710SBarry Smith .  nfails - number of failed solves
14803d4c4710SBarry Smith 
14819d85da0cSMatthew G. Knepley    Level: intermediate
14829d85da0cSMatthew G. Knepley 
14839d85da0cSMatthew G. Knepley    Options Database Keys:
14849d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
14859d85da0cSMatthew G. Knepley 
14863d4c4710SBarry Smith    Notes:
14873d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
14883d4c4710SBarry Smith 
1489e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
14903d4c4710SBarry Smith @*/
14917087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
14923d4c4710SBarry Smith {
14933d4c4710SBarry Smith   PetscFunctionBegin;
14940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14953d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
14963d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
14973d4c4710SBarry Smith   PetscFunctionReturn(0);
14983d4c4710SBarry Smith }
14993d4c4710SBarry Smith 
15003d4c4710SBarry Smith /*@
15013d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
15023d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
15033d4c4710SBarry Smith 
15043f9fe445SBarry Smith    Logically Collective on SNES
15053d4c4710SBarry Smith 
15063d4c4710SBarry Smith    Input Parameters:
15073d4c4710SBarry Smith +  snes     - SNES context
15083d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
15093d4c4710SBarry Smith 
15103d4c4710SBarry Smith    Level: intermediate
15113d4c4710SBarry Smith 
15129d85da0cSMatthew G. Knepley    Options Database Keys:
15139d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15149d85da0cSMatthew G. Knepley 
151595452b02SPatrick Sanan    Notes:
151695452b02SPatrick Sanan     By default this is 0; that is SNES returns on the first failed linear solve
15173d4c4710SBarry Smith 
151858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
15193d4c4710SBarry Smith @*/
15207087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
15213d4c4710SBarry Smith {
15223d4c4710SBarry Smith   PetscFunctionBegin;
15230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1524c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
15253d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
15263d4c4710SBarry Smith   PetscFunctionReturn(0);
15273d4c4710SBarry Smith }
15283d4c4710SBarry Smith 
15293d4c4710SBarry Smith /*@
15303d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
15313d4c4710SBarry Smith      are allowed before SNES terminates
15323d4c4710SBarry Smith 
15333d4c4710SBarry Smith    Not Collective
15343d4c4710SBarry Smith 
15353d4c4710SBarry Smith    Input Parameter:
15363d4c4710SBarry Smith .  snes     - SNES context
15373d4c4710SBarry Smith 
15383d4c4710SBarry Smith    Output Parameter:
15393d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
15403d4c4710SBarry Smith 
15413d4c4710SBarry Smith    Level: intermediate
15423d4c4710SBarry Smith 
154395452b02SPatrick Sanan    Notes:
154495452b02SPatrick Sanan     By default this is 1; that is SNES returns on the first failed linear solve
15453d4c4710SBarry Smith 
1546e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
15473d4c4710SBarry Smith @*/
15487087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
15493d4c4710SBarry Smith {
15503d4c4710SBarry Smith   PetscFunctionBegin;
15510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15523d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
15533d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
15543d4c4710SBarry Smith   PetscFunctionReturn(0);
15553d4c4710SBarry Smith }
15563d4c4710SBarry Smith 
1557c96a6f78SLois Curfman McInnes /*@
1558b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1559c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1560c96a6f78SLois Curfman McInnes 
1561c7afd0dbSLois Curfman McInnes    Not Collective
1562c7afd0dbSLois Curfman McInnes 
1563c96a6f78SLois Curfman McInnes    Input Parameter:
1564c96a6f78SLois Curfman McInnes .  snes - SNES context
1565c96a6f78SLois Curfman McInnes 
1566c96a6f78SLois Curfman McInnes    Output Parameter:
1567c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1568c96a6f78SLois Curfman McInnes 
1569c96a6f78SLois Curfman McInnes    Notes:
1570971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1571c96a6f78SLois Curfman McInnes 
1572010be392SBarry 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
1573010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1574010be392SBarry Smith 
157536851e7fSLois Curfman McInnes    Level: intermediate
157636851e7fSLois Curfman McInnes 
157771dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1578c96a6f78SLois Curfman McInnes @*/
15797087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1580c96a6f78SLois Curfman McInnes {
15813a40ed3dSBarry Smith   PetscFunctionBegin;
15820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15834482741eSBarry Smith   PetscValidIntPointer(lits,2);
1584c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
15853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1586c96a6f78SLois Curfman McInnes }
1587c96a6f78SLois Curfman McInnes 
1588971e163fSPeter Brune /*@
1589971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1590971e163fSPeter Brune    are reset every time SNESSolve() is called.
1591971e163fSPeter Brune 
1592971e163fSPeter Brune    Logically Collective on SNES
1593971e163fSPeter Brune 
1594971e163fSPeter Brune    Input Parameter:
1595971e163fSPeter Brune +  snes - SNES context
1596971e163fSPeter Brune -  reset - whether to reset the counters or not
1597971e163fSPeter Brune 
1598971e163fSPeter Brune    Notes:
1599fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1600971e163fSPeter Brune 
1601971e163fSPeter Brune    Level: developer
1602971e163fSPeter Brune 
1603734794cfSBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
1604971e163fSPeter Brune @*/
1605971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1606971e163fSPeter Brune {
1607971e163fSPeter Brune   PetscFunctionBegin;
1608971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1609971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1610971e163fSPeter Brune   snes->counters_reset = reset;
1611971e163fSPeter Brune   PetscFunctionReturn(0);
1612971e163fSPeter Brune }
1613971e163fSPeter Brune 
161482bf6240SBarry Smith 
16152999313aSBarry Smith /*@
16162999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
16172999313aSBarry Smith 
16182999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
16192999313aSBarry Smith 
16202999313aSBarry Smith    Input Parameters:
16212999313aSBarry Smith +  snes - the SNES context
16222999313aSBarry Smith -  ksp - the KSP context
16232999313aSBarry Smith 
16242999313aSBarry Smith    Notes:
16252999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
16262999313aSBarry Smith    so this routine is rarely needed.
16272999313aSBarry Smith 
16282999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
16292999313aSBarry Smith    decreased by one.
16302999313aSBarry Smith 
16312999313aSBarry Smith    Level: developer
16322999313aSBarry Smith 
16332999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
16342999313aSBarry Smith @*/
16357087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
16362999313aSBarry Smith {
16372999313aSBarry Smith   PetscErrorCode ierr;
16382999313aSBarry Smith 
16392999313aSBarry Smith   PetscFunctionBegin;
16400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16410700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
16422999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
16437dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1644906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
16452999313aSBarry Smith   snes->ksp = ksp;
16462999313aSBarry Smith   PetscFunctionReturn(0);
16472999313aSBarry Smith }
16482999313aSBarry Smith 
16499b94acceSBarry Smith /* -----------------------------------------------------------*/
165052baeb72SSatish Balay /*@
16519b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
16529b94acceSBarry Smith 
1653d083f849SBarry Smith    Collective
1654c7afd0dbSLois Curfman McInnes 
1655c7afd0dbSLois Curfman McInnes    Input Parameters:
1656906ed7ccSBarry Smith .  comm - MPI communicator
16579b94acceSBarry Smith 
16589b94acceSBarry Smith    Output Parameter:
16599b94acceSBarry Smith .  outsnes - the new SNES context
16609b94acceSBarry Smith 
1661c7afd0dbSLois Curfman McInnes    Options Database Keys:
1662c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1663c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1664c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1665c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1666c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1667c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1668c1f60f51SBarry Smith 
166936851e7fSLois Curfman McInnes    Level: beginner
167036851e7fSLois Curfman McInnes 
167195452b02SPatrick Sanan    Developer Notes:
167295452b02SPatrick Sanan     SNES always creates a KSP object even though many SNES methods do not use it. This is
1673efd4aadfSBarry Smith                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1674efd4aadfSBarry Smith                     particular method does use KSP and regulates if the information about the KSP is printed
1675efd4aadfSBarry Smith                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1676efd4aadfSBarry Smith                     by help messages about meaningless SNES options.
1677efd4aadfSBarry Smith 
1678efd4aadfSBarry Smith                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1679efd4aadfSBarry Smith                     be fixed.
1680efd4aadfSBarry Smith 
16813d5a8a6aSBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1682a8054027SBarry Smith 
16839b94acceSBarry Smith @*/
16847087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
16859b94acceSBarry Smith {
1686dfbe8321SBarry Smith   PetscErrorCode ierr;
16879b94acceSBarry Smith   SNES           snes;
1688fa9f3622SBarry Smith   SNESKSPEW      *kctx;
168937fcc0dbSBarry Smith 
16903a40ed3dSBarry Smith   PetscFunctionBegin;
1691ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
16920298fd71SBarry Smith   *outsnes = NULL;
1693607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
16948ba1e511SMatthew Knepley 
169573107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
16967adad957SLisandro Dalcin 
16978d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
16982c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
169988976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
17009b94acceSBarry Smith   snes->max_its           = 50;
17019750a799SBarry Smith   snes->max_funcs         = 10000;
17029b94acceSBarry Smith   snes->norm              = 0.0;
1703c1e67a49SFande Kong   snes->xnorm             = 0.0;
1704c1e67a49SFande Kong   snes->ynorm             = 0.0;
1705365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
17066c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
17073a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17083a2046daSBarry Smith   snes->rtol              = 1.e-5;
17093a2046daSBarry Smith #else
1710b4874afaSBarry Smith   snes->rtol              = 1.e-8;
17113a2046daSBarry Smith #endif
1712b4874afaSBarry Smith   snes->ttol              = 0.0;
17133a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17143a2046daSBarry Smith   snes->abstol            = 1.e-25;
17153a2046daSBarry Smith #else
171670441072SBarry Smith   snes->abstol            = 1.e-50;
17173a2046daSBarry Smith #endif
17187cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
17197cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
17207cd0ae37SLisandro Dalcin #else
1721c60f73f4SPeter Brune   snes->stol              = 1.e-8;
17227cd0ae37SLisandro Dalcin #endif
17233a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17243a2046daSBarry Smith   snes->deltatol          = 1.e-6;
17253a2046daSBarry Smith #else
17264b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
17273a2046daSBarry Smith #endif
1728e37c518bSBarry Smith   snes->divtol            = 1.e4;
1729e37c518bSBarry Smith   snes->rnorm0            = 0;
17309b94acceSBarry Smith   snes->nfuncs            = 0;
173150ffb88aSMatthew Knepley   snes->numFailures       = 0;
173250ffb88aSMatthew Knepley   snes->maxFailures       = 1;
17337a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1734e35cf81dSBarry Smith   snes->lagjacobian       = 1;
173537ec4e1aSPeter Brune   snes->jac_iter          = 0;
173637ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1737a8054027SBarry Smith   snes->lagpreconditioner = 1;
173837ec4e1aSPeter Brune   snes->pre_iter          = 0;
173937ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1740639f9d9dSBarry Smith   snes->numbermonitors    = 0;
1741c4421ceaSFande Kong   snes->numberreasonviews = 0;
17429e5d0892SLisandro Dalcin   snes->data              = NULL;
17434dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1744186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
17456f24a144SLois Curfman McInnes   snes->nwork             = 0;
17469e5d0892SLisandro Dalcin   snes->work              = NULL;
174758c9b817SLisandro Dalcin   snes->nvwork            = 0;
17489e5d0892SLisandro Dalcin   snes->vwork             = NULL;
1749758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1750758f92a0SBarry Smith   snes->conv_hist_max     = 0;
17510298fd71SBarry Smith   snes->conv_hist         = NULL;
17520298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1753758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1754971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1755e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1756184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1757efd4aadfSBarry Smith   snes->npcside           = PC_RIGHT;
1758b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled = 0;
1759c40d0f55SPeter Brune 
1760d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1761d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1762d8f46077SPeter Brune   snes->mf_version  = 1;
1763d8f46077SPeter Brune 
17643d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
17653d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
17663d4c4710SBarry Smith 
1767349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
176876bd3646SJed Brown   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1769349187a7SBarry Smith 
17704fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
17714fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
17724fc747eaSLawrence Mitchell 
17739b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1774b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1775f5af7f23SKarl Rupp 
17769b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
17779b94acceSBarry Smith   kctx->version     = 2;
17789b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
17799b94acceSBarry Smith                              this was too large for some test cases */
178075567043SBarry Smith   kctx->rtol_last   = 0.0;
17819b94acceSBarry Smith   kctx->rtol_max    = .9;
17829b94acceSBarry Smith   kctx->gamma       = 1.0;
178362d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
178471f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
17859b94acceSBarry Smith   kctx->threshold   = .1;
178675567043SBarry Smith   kctx->lresid_last = 0.0;
178775567043SBarry Smith   kctx->norm_last   = 0.0;
17889b94acceSBarry Smith 
17899b94acceSBarry Smith   *outsnes = snes;
17903a40ed3dSBarry Smith   PetscFunctionReturn(0);
17919b94acceSBarry Smith }
17929b94acceSBarry Smith 
179388f0584fSBarry Smith /*MC
1794411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
179588f0584fSBarry Smith 
179688f0584fSBarry Smith      Synopsis:
1797411c0326SBarry Smith      #include "petscsnes.h"
1798411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
179988f0584fSBarry Smith 
18001843f636SBarry Smith      Collective on snes
18011843f636SBarry Smith 
180288f0584fSBarry Smith      Input Parameters:
180388f0584fSBarry Smith +     snes - the SNES context
180488f0584fSBarry Smith .     x    - state at which to evaluate residual
180588f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
180688f0584fSBarry Smith 
180788f0584fSBarry Smith      Output Parameter:
180888f0584fSBarry Smith .     f  - vector to put residual (function value)
180988f0584fSBarry Smith 
1810878cb397SSatish Balay    Level: intermediate
1811878cb397SSatish Balay 
181288f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
181388f0584fSBarry Smith M*/
181488f0584fSBarry Smith 
18159b94acceSBarry Smith /*@C
18169b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
18179b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
18189b94acceSBarry Smith    equations.
18199b94acceSBarry Smith 
18203f9fe445SBarry Smith    Logically Collective on SNES
1821fee21e36SBarry Smith 
1822c7afd0dbSLois Curfman McInnes    Input Parameters:
1823c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1824c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1825f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1826c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
18270298fd71SBarry Smith          function evaluation routine (may be NULL)
18289b94acceSBarry Smith 
18299b94acceSBarry Smith    Notes:
18309b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
18319b94acceSBarry Smith $      f'(x) x = -f(x),
1832c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
18339b94acceSBarry Smith 
183436851e7fSLois Curfman McInnes    Level: beginner
183536851e7fSLois Curfman McInnes 
1836bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
18379b94acceSBarry Smith @*/
1838f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
18399b94acceSBarry Smith {
184085385478SLisandro Dalcin   PetscErrorCode ierr;
18416cab3a1bSJed Brown   DM             dm;
18426cab3a1bSJed Brown 
18433a40ed3dSBarry Smith   PetscFunctionBegin;
18440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1845d2a683ecSLisandro Dalcin   if (r) {
1846d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1847d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
184885385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
18496bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1850f5af7f23SKarl Rupp 
185185385478SLisandro Dalcin     snes->vec_func = r;
1852d2a683ecSLisandro Dalcin   }
18536cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1854f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
18553a40ed3dSBarry Smith   PetscFunctionReturn(0);
18569b94acceSBarry Smith }
18579b94acceSBarry Smith 
1858646217ecSPeter Brune 
1859e4ed7901SPeter Brune /*@C
1860e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1861e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1862e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1863e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1864e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1865e4ed7901SPeter Brune 
1866e4ed7901SPeter Brune    Logically Collective on SNES
1867e4ed7901SPeter Brune 
1868e4ed7901SPeter Brune    Input Parameters:
1869e4ed7901SPeter Brune +  snes - the SNES context
1870e4ed7901SPeter Brune -  f - vector to store function value
1871e4ed7901SPeter Brune 
1872e4ed7901SPeter Brune    Notes:
1873e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1874e4ed7901SPeter Brune 
1875e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1876e4ed7901SPeter Brune 
1877e4ed7901SPeter Brune    Level: developer
1878e4ed7901SPeter Brune 
1879e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1880e4ed7901SPeter Brune @*/
1881e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1882e4ed7901SPeter Brune {
1883e4ed7901SPeter Brune   PetscErrorCode ierr;
1884e4ed7901SPeter Brune   Vec            vec_func;
1885e4ed7901SPeter Brune 
1886e4ed7901SPeter Brune   PetscFunctionBegin;
1887e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1888e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1889e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1890efd4aadfSBarry Smith   if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1891902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1892902f982fSPeter Brune     PetscFunctionReturn(0);
1893902f982fSPeter Brune   }
18940298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1895e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1896f5af7f23SKarl Rupp 
1897217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1898e4ed7901SPeter Brune   PetscFunctionReturn(0);
1899e4ed7901SPeter Brune }
1900e4ed7901SPeter Brune 
1901534ebe21SPeter Brune /*@
1902365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1903534ebe21SPeter Brune    of the SNES method.
1904534ebe21SPeter Brune 
1905534ebe21SPeter Brune    Logically Collective on SNES
1906534ebe21SPeter Brune 
1907534ebe21SPeter Brune    Input Parameters:
1908534ebe21SPeter Brune +  snes - the SNES context
1909365a6726SPeter Brune -  normschedule - the frequency of norm computation
1910534ebe21SPeter Brune 
1911517f1916SMatthew G. Knepley    Options Database Key:
1912517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1913517f1916SMatthew G. Knepley 
1914534ebe21SPeter Brune    Notes:
1915365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1916534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1917534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1918be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1919534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1920534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1921534ebe21SPeter Brune    their solution.
1922534ebe21SPeter Brune 
1923534ebe21SPeter Brune    Level: developer
1924534ebe21SPeter Brune 
1925365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1926534ebe21SPeter Brune @*/
1927365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1928534ebe21SPeter Brune {
1929534ebe21SPeter Brune   PetscFunctionBegin;
1930534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1931365a6726SPeter Brune   snes->normschedule = normschedule;
1932534ebe21SPeter Brune   PetscFunctionReturn(0);
1933534ebe21SPeter Brune }
1934534ebe21SPeter Brune 
1935534ebe21SPeter Brune 
1936534ebe21SPeter Brune /*@
1937365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1938534ebe21SPeter Brune    of the SNES method.
1939534ebe21SPeter Brune 
1940534ebe21SPeter Brune    Logically Collective on SNES
1941534ebe21SPeter Brune 
1942534ebe21SPeter Brune    Input Parameters:
1943534ebe21SPeter Brune +  snes - the SNES context
1944365a6726SPeter Brune -  normschedule - the type of the norm used
1945534ebe21SPeter Brune 
1946534ebe21SPeter Brune    Level: advanced
1947534ebe21SPeter Brune 
1948365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1949534ebe21SPeter Brune @*/
1950365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1951534ebe21SPeter Brune {
1952534ebe21SPeter Brune   PetscFunctionBegin;
1953534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1954365a6726SPeter Brune   *normschedule = snes->normschedule;
1955534ebe21SPeter Brune   PetscFunctionReturn(0);
1956534ebe21SPeter Brune }
1957534ebe21SPeter Brune 
195847073ea2SPeter Brune 
1959c5ce4427SMatthew G. Knepley /*@
1960c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1961c5ce4427SMatthew G. Knepley 
1962c5ce4427SMatthew G. Knepley   Logically Collective on SNES
1963c5ce4427SMatthew G. Knepley 
1964c5ce4427SMatthew G. Knepley   Input Parameters:
1965c5ce4427SMatthew G. Knepley + snes - the SNES context
1966c5ce4427SMatthew G. Knepley 
1967c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
1968c5ce4427SMatthew G. Knepley 
1969c5ce4427SMatthew G. Knepley   Level: developer
1970c5ce4427SMatthew G. Knepley 
1971c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1972c5ce4427SMatthew G. Knepley @*/
1973c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1974c5ce4427SMatthew G. Knepley {
1975c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1976c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1977c5ce4427SMatthew G. Knepley   snes->norm = norm;
1978c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1979c5ce4427SMatthew G. Knepley }
1980c5ce4427SMatthew G. Knepley 
1981c5ce4427SMatthew G. Knepley /*@
1982c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
1983c5ce4427SMatthew G. Knepley 
1984c5ce4427SMatthew G. Knepley   Not Collective
1985c5ce4427SMatthew G. Knepley 
1986c5ce4427SMatthew G. Knepley   Input Parameter:
1987c5ce4427SMatthew G. Knepley . snes - the SNES context
1988c5ce4427SMatthew G. Knepley 
1989c5ce4427SMatthew G. Knepley   Output Parameter:
1990c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
1991c5ce4427SMatthew G. Knepley 
1992c5ce4427SMatthew G. Knepley   Level: developer
1993c5ce4427SMatthew G. Knepley 
1994c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1995c5ce4427SMatthew G. Knepley @*/
1996c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
1997c5ce4427SMatthew G. Knepley {
1998c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1999c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2000c5ce4427SMatthew G. Knepley   PetscValidPointer(norm, 2);
2001c5ce4427SMatthew G. Knepley   *norm = snes->norm;
2002c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
2003c5ce4427SMatthew G. Knepley }
2004c5ce4427SMatthew G. Knepley 
2005c1e67a49SFande Kong /*@
2006c1e67a49SFande Kong   SNESGetUpdateNorm - Gets the last computed norm of the Newton update
2007c1e67a49SFande Kong 
2008c1e67a49SFande Kong   Not Collective
2009c1e67a49SFande Kong 
2010c1e67a49SFande Kong   Input Parameter:
2011c1e67a49SFande Kong . snes - the SNES context
2012c1e67a49SFande Kong 
2013c1e67a49SFande Kong   Output Parameter:
2014c1e67a49SFande Kong . ynorm - the last computed update norm
2015c1e67a49SFande Kong 
2016c1e67a49SFande Kong   Level: developer
2017c1e67a49SFande Kong 
2018c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm()
2019c1e67a49SFande Kong @*/
2020c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2021c1e67a49SFande Kong {
2022c1e67a49SFande Kong   PetscFunctionBegin;
2023c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2024c1e67a49SFande Kong   PetscValidPointer(ynorm, 2);
2025c1e67a49SFande Kong   *ynorm = snes->ynorm;
2026c1e67a49SFande Kong   PetscFunctionReturn(0);
2027c1e67a49SFande Kong }
2028c1e67a49SFande Kong 
2029c1e67a49SFande Kong /*@
20304591eaf2SFande Kong   SNESGetSolutionNorm - Gets the last computed norm of the solution
2031c1e67a49SFande Kong 
2032c1e67a49SFande Kong   Not Collective
2033c1e67a49SFande Kong 
2034c1e67a49SFande Kong   Input Parameter:
2035c1e67a49SFande Kong . snes - the SNES context
2036c1e67a49SFande Kong 
2037c1e67a49SFande Kong   Output Parameter:
2038c1e67a49SFande Kong . xnorm - the last computed solution norm
2039c1e67a49SFande Kong 
2040c1e67a49SFande Kong   Level: developer
2041c1e67a49SFande Kong 
2042c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm(), SNESGetUpdateNorm()
2043c1e67a49SFande Kong @*/
2044c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2045c1e67a49SFande Kong {
2046c1e67a49SFande Kong   PetscFunctionBegin;
2047c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2048c1e67a49SFande Kong   PetscValidPointer(xnorm, 2);
2049c1e67a49SFande Kong   *xnorm = snes->xnorm;
2050c1e67a49SFande Kong   PetscFunctionReturn(0);
2051c1e67a49SFande Kong }
2052c1e67a49SFande Kong 
205347073ea2SPeter Brune /*@C
205447073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
205547073ea2SPeter Brune    of the SNES method.
205647073ea2SPeter Brune 
205747073ea2SPeter Brune    Logically Collective on SNES
205847073ea2SPeter Brune 
205947073ea2SPeter Brune    Input Parameters:
206047073ea2SPeter Brune +  snes - the SNES context
206147073ea2SPeter Brune -  normschedule - the frequency of norm computation
206247073ea2SPeter Brune 
206347073ea2SPeter Brune    Notes:
206447073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
206547073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
206647073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
2067be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
206847073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
206947073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
207047073ea2SPeter Brune    their solution.
207147073ea2SPeter Brune 
207247073ea2SPeter Brune    Level: developer
207347073ea2SPeter Brune 
207447073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
207547073ea2SPeter Brune @*/
207647073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
207747073ea2SPeter Brune {
207847073ea2SPeter Brune   PetscFunctionBegin;
207947073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
208047073ea2SPeter Brune   snes->functype = type;
208147073ea2SPeter Brune   PetscFunctionReturn(0);
208247073ea2SPeter Brune }
208347073ea2SPeter Brune 
208447073ea2SPeter Brune 
208547073ea2SPeter Brune /*@C
208647073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
208747073ea2SPeter Brune    of the SNES method.
208847073ea2SPeter Brune 
208947073ea2SPeter Brune    Logically Collective on SNES
209047073ea2SPeter Brune 
209147073ea2SPeter Brune    Input Parameters:
209247073ea2SPeter Brune +  snes - the SNES context
209347073ea2SPeter Brune -  normschedule - the type of the norm used
209447073ea2SPeter Brune 
209547073ea2SPeter Brune    Level: advanced
209647073ea2SPeter Brune 
209747073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
209847073ea2SPeter Brune @*/
209947073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
210047073ea2SPeter Brune {
210147073ea2SPeter Brune   PetscFunctionBegin;
210247073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
210347073ea2SPeter Brune   *type = snes->functype;
2104534ebe21SPeter Brune   PetscFunctionReturn(0);
2105534ebe21SPeter Brune }
2106534ebe21SPeter Brune 
2107bf388a1fSBarry Smith /*MC
2108be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
2109bf388a1fSBarry Smith 
2110bf388a1fSBarry Smith      Synopsis:
2111aaa7dc30SBarry Smith      #include <petscsnes.h>
2112be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
2113bf388a1fSBarry Smith 
21141843f636SBarry Smith      Collective on snes
21151843f636SBarry Smith 
21161843f636SBarry Smith      Input Parameters:
2117bf388a1fSBarry Smith +  X   - solution vector
2118bf388a1fSBarry Smith .  B   - RHS vector
2119bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
2120bf388a1fSBarry Smith 
21211843f636SBarry Smith      Output Parameter:
21221843f636SBarry Smith .  X   - solution vector
21231843f636SBarry Smith 
2124878cb397SSatish Balay    Level: intermediate
2125878cb397SSatish Balay 
2126be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
2127bf388a1fSBarry Smith M*/
2128bf388a1fSBarry Smith 
2129c79ef259SPeter Brune /*@C
2130be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2131c79ef259SPeter Brune    use with composed nonlinear solvers.
2132c79ef259SPeter Brune 
2133c79ef259SPeter Brune    Input Parameters:
2134c79ef259SPeter Brune +  snes   - the SNES context
2135be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
2136c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
21370298fd71SBarry Smith             smoother evaluation routine (may be NULL)
2138c79ef259SPeter Brune 
2139c79ef259SPeter Brune    Notes:
2140be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
2141c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
2142c79ef259SPeter Brune 
2143d28543b3SPeter Brune    Level: intermediate
2144c79ef259SPeter Brune 
2145be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
2146c79ef259SPeter Brune @*/
2147be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
21486cab3a1bSJed Brown {
21496cab3a1bSJed Brown   PetscErrorCode ierr;
21506cab3a1bSJed Brown   DM             dm;
21516cab3a1bSJed Brown 
2152646217ecSPeter Brune   PetscFunctionBegin;
21536cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21546cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2155be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
2156646217ecSPeter Brune   PetscFunctionReturn(0);
2157646217ecSPeter Brune }
2158646217ecSPeter Brune 
215925acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
21608b0a5094SBarry Smith {
21618b0a5094SBarry Smith   PetscErrorCode ierr;
2162e03ab78fSPeter Brune   DM             dm;
2163942e3340SBarry Smith   DMSNES         sdm;
21646cab3a1bSJed Brown 
21658b0a5094SBarry Smith   PetscFunctionBegin;
2166e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2167942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
216825acbd8eSLisandro Dalcin   if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
216925acbd8eSLisandro Dalcin   if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
21708b0a5094SBarry Smith   /*  A(x)*x - b(x) */
217125acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user function");
217222c6f798SBarry Smith   ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
217325acbd8eSLisandro Dalcin   PetscStackPop;
217425acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user Jacobian");
2175d1e9a80fSBarry Smith   ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
217625acbd8eSLisandro Dalcin   PetscStackPop;
21778b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
217895eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
21798b0a5094SBarry Smith   PetscFunctionReturn(0);
21808b0a5094SBarry Smith }
21818b0a5094SBarry Smith 
218225acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
21838b0a5094SBarry Smith {
21848b0a5094SBarry Smith   PetscFunctionBegin;
2185e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
21868b0a5094SBarry Smith   PetscFunctionReturn(0);
21878b0a5094SBarry Smith }
21888b0a5094SBarry Smith 
21898b0a5094SBarry Smith /*@C
21900d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
21918b0a5094SBarry Smith 
21928b0a5094SBarry Smith    Logically Collective on SNES
21938b0a5094SBarry Smith 
21948b0a5094SBarry Smith    Input Parameters:
21958b0a5094SBarry Smith +  snes - the SNES context
21968b0a5094SBarry Smith .  r - vector to store function value
2197f8b49ee9SBarry Smith .  b - function evaluation routine
2198e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
2199e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
2200411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
22018b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
22020298fd71SBarry Smith          function evaluation routine (may be NULL)
22038b0a5094SBarry Smith 
22048b0a5094SBarry Smith    Notes:
2205f450aa47SBarry Smith     We do not recomemend using this routine. It is far better to provide the nonlinear function F() and some approximation to the Jacobian and use
2206f450aa47SBarry 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.
2207f450aa47SBarry Smith 
22088b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
22098b0a5094SBarry Smith 
22108b0a5094SBarry Smith $     Solves the equation A(x) x = b(x) via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = b(x^{n}) - A(x^{n})x^{n}
22118b0a5094SBarry Smith $     Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = b(x^{n}) iteration.
22128b0a5094SBarry Smith 
22138b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
22148b0a5094SBarry Smith 
22150d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
22160d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
22178b0a5094SBarry Smith 
22188b0a5094SBarry 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
22198b0a5094SBarry 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
22208b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
22218b0a5094SBarry Smith 
2222f450aa47SBarry Smith    Level: intermediate
22238b0a5094SBarry Smith 
2224411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
22258b0a5094SBarry Smith @*/
2226d1e9a80fSBarry Smith PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*b)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
22278b0a5094SBarry Smith {
22288b0a5094SBarry Smith   PetscErrorCode ierr;
2229e03ab78fSPeter Brune   DM             dm;
2230e03ab78fSPeter Brune 
22318b0a5094SBarry Smith   PetscFunctionBegin;
22328b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2233e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
2234f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
22358b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
2236e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
22378b0a5094SBarry Smith   PetscFunctionReturn(0);
22388b0a5094SBarry Smith }
22398b0a5094SBarry Smith 
22407971a8bfSPeter Brune /*@C
22417971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
22427971a8bfSPeter Brune 
22437971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
22447971a8bfSPeter Brune 
22457971a8bfSPeter Brune    Input Parameter:
22467971a8bfSPeter Brune .  snes - the SNES context
22477971a8bfSPeter Brune 
22487971a8bfSPeter Brune    Output Parameter:
22490298fd71SBarry Smith +  r - the function (or NULL)
2250f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
2251e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2252e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2253f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
22540298fd71SBarry Smith -  ctx - the function context (or NULL)
22557971a8bfSPeter Brune 
22567971a8bfSPeter Brune    Level: advanced
22577971a8bfSPeter Brune 
2258e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
22597971a8bfSPeter Brune @*/
2260d1e9a80fSBarry 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)
22617971a8bfSPeter Brune {
22627971a8bfSPeter Brune   PetscErrorCode ierr;
22637971a8bfSPeter Brune   DM             dm;
22647971a8bfSPeter Brune 
22657971a8bfSPeter Brune   PetscFunctionBegin;
22667971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22670298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2268e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
22697971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2270f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
22717971a8bfSPeter Brune   PetscFunctionReturn(0);
22727971a8bfSPeter Brune }
22737971a8bfSPeter Brune 
2274d25893d9SBarry Smith /*@C
2275d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2276d25893d9SBarry Smith 
2277d25893d9SBarry Smith    Logically Collective on SNES
2278d25893d9SBarry Smith 
2279d25893d9SBarry Smith    Input Parameters:
2280d25893d9SBarry Smith +  snes - the SNES context
2281d25893d9SBarry Smith .  func - function evaluation routine
2282d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
22830298fd71SBarry Smith          function evaluation routine (may be NULL)
2284d25893d9SBarry Smith 
2285d25893d9SBarry Smith    Calling sequence of func:
2286d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2287d25893d9SBarry Smith 
2288d25893d9SBarry Smith .  f - function vector
2289d25893d9SBarry Smith -  ctx - optional user-defined function context
2290d25893d9SBarry Smith 
2291d25893d9SBarry Smith    Level: intermediate
2292d25893d9SBarry Smith 
2293d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2294d25893d9SBarry Smith @*/
2295d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2296d25893d9SBarry Smith {
2297d25893d9SBarry Smith   PetscFunctionBegin;
2298d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2299d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2300d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2301d25893d9SBarry Smith   PetscFunctionReturn(0);
2302d25893d9SBarry Smith }
2303d25893d9SBarry Smith 
23043ab0aad5SBarry Smith /* --------------------------------------------------------------- */
23051096aae1SMatthew Knepley /*@C
23061096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
23071096aae1SMatthew Knepley    it assumes a zero right hand side.
23081096aae1SMatthew Knepley 
23093f9fe445SBarry Smith    Logically Collective on SNES
23101096aae1SMatthew Knepley 
23111096aae1SMatthew Knepley    Input Parameter:
23121096aae1SMatthew Knepley .  snes - the SNES context
23131096aae1SMatthew Knepley 
23141096aae1SMatthew Knepley    Output Parameter:
23150298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
23161096aae1SMatthew Knepley 
23171096aae1SMatthew Knepley    Level: intermediate
23181096aae1SMatthew Knepley 
231985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
23201096aae1SMatthew Knepley @*/
23217087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
23221096aae1SMatthew Knepley {
23231096aae1SMatthew Knepley   PetscFunctionBegin;
23240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23251096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
232685385478SLisandro Dalcin   *rhs = snes->vec_rhs;
23271096aae1SMatthew Knepley   PetscFunctionReturn(0);
23281096aae1SMatthew Knepley }
23291096aae1SMatthew Knepley 
23309b94acceSBarry Smith /*@
2331bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
23329b94acceSBarry Smith 
2333c7afd0dbSLois Curfman McInnes    Collective on SNES
2334c7afd0dbSLois Curfman McInnes 
23359b94acceSBarry Smith    Input Parameters:
2336c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2337c7afd0dbSLois Curfman McInnes -  x - input vector
23389b94acceSBarry Smith 
23399b94acceSBarry Smith    Output Parameter:
23403638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
23419b94acceSBarry Smith 
23421bffabb2SLois Curfman McInnes    Notes:
234336851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
234436851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
234536851e7fSLois Curfman McInnes    themselves.
234636851e7fSLois Curfman McInnes 
234736851e7fSLois Curfman McInnes    Level: developer
234836851e7fSLois Curfman McInnes 
2349a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
23509b94acceSBarry Smith @*/
23517087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
23529b94acceSBarry Smith {
2353dfbe8321SBarry Smith   PetscErrorCode ierr;
23546cab3a1bSJed Brown   DM             dm;
2355942e3340SBarry Smith   DMSNES         sdm;
23569b94acceSBarry Smith 
23573a40ed3dSBarry Smith   PetscFunctionBegin;
23580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23590700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
23600700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2361c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2362c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
236362796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2364184914b5SBarry Smith 
23656cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2366942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
236732f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
236894db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2369ccf3c845SPeter Brune       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
237094db00ebSBarry Smith     }
23718860a134SJunchao Zhang     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2372d64ed03dSBarry Smith     PetscStackPush("SNES user function");
23738ddeebeaSSteve Benbow     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
23748ddeebeaSSteve Benbow     snes->domainerror = PETSC_FALSE;
237522c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2376d64ed03dSBarry Smith     PetscStackPop;
23778860a134SJunchao Zhang     ierr = VecLockReadPop(x);CHKERRQ(ierr);
237894db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2379ccf3c845SPeter Brune       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
238094db00ebSBarry Smith     }
2381c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2382c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2383644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
238485385478SLisandro Dalcin   if (snes->vec_rhs) {
238585385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
23863ab0aad5SBarry Smith   }
2387ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2388422a814eSBarry Smith   /*
2389422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2390422a814eSBarry Smith      propagate the value to all processes
2391422a814eSBarry Smith   */
2392422a814eSBarry Smith   if (snes->domainerror) {
2393422a814eSBarry Smith     ierr = VecSetInf(y);CHKERRQ(ierr);
2394422a814eSBarry Smith   }
23953a40ed3dSBarry Smith   PetscFunctionReturn(0);
23969b94acceSBarry Smith }
23979b94acceSBarry Smith 
2398c79ef259SPeter Brune /*@
2399be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2400c79ef259SPeter Brune 
2401c79ef259SPeter Brune    Collective on SNES
2402c79ef259SPeter Brune 
2403c79ef259SPeter Brune    Input Parameters:
2404c79ef259SPeter Brune +  snes - the SNES context
2405c79ef259SPeter Brune .  x - input vector
2406c79ef259SPeter Brune -  b - rhs vector
2407c79ef259SPeter Brune 
2408c79ef259SPeter Brune    Output Parameter:
2409c79ef259SPeter Brune .  x - new solution vector
2410c79ef259SPeter Brune 
2411c79ef259SPeter Brune    Notes:
2412be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2413c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2414c79ef259SPeter Brune    themselves.
2415c79ef259SPeter Brune 
2416c79ef259SPeter Brune    Level: developer
2417c79ef259SPeter Brune 
2418be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2419c79ef259SPeter Brune @*/
2420be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2421646217ecSPeter Brune {
2422646217ecSPeter Brune   PetscErrorCode ierr;
24236cab3a1bSJed Brown   DM             dm;
2424942e3340SBarry Smith   DMSNES         sdm;
2425646217ecSPeter Brune 
2426646217ecSPeter Brune   PetscFunctionBegin;
2427646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2428646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2429646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2430646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2431646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
243262796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2433be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
24346cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2435942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
243622c6f798SBarry Smith   if (sdm->ops->computegs) {
24378860a134SJunchao Zhang     if (b) {ierr = VecLockReadPush(b);CHKERRQ(ierr);}
2438be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
243922c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2440646217ecSPeter Brune     PetscStackPop;
24418860a134SJunchao Zhang     if (b) {ierr = VecLockReadPop(b);CHKERRQ(ierr);}
2442be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2443be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2444646217ecSPeter Brune   PetscFunctionReturn(0);
2445646217ecSPeter Brune }
2446646217ecSPeter Brune 
2447e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes)
2448e885f1abSBarry Smith {
244912837594SBarry Smith   Mat               A,B,C,D,jacobian;
2450e885f1abSBarry Smith   Vec               x = snes->vec_sol,f = snes->vec_func;
2451e885f1abSBarry Smith   PetscErrorCode    ierr;
2452e885f1abSBarry Smith   PetscReal         nrm,gnorm;
245381e7118cSBarry Smith   PetscReal         threshold = 1.e-5;
24540e276705SLisandro Dalcin   MatType           mattype;
2455e885f1abSBarry Smith   PetscInt          m,n,M,N;
2456e885f1abSBarry Smith   void              *functx;
24572cd624f9SStefano Zampini   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose;
24583325ff46SBarry Smith   PetscViewer       viewer,mviewer;
2459e885f1abSBarry Smith   MPI_Comm          comm;
2460e885f1abSBarry Smith   PetscInt          tabs;
246112837594SBarry Smith   static PetscBool  directionsprinted = PETSC_FALSE;
24623325ff46SBarry Smith   PetscViewerFormat format;
2463e885f1abSBarry Smith 
2464e885f1abSBarry Smith   PetscFunctionBegin;
2465fc35ed60SBarry Smith   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
246612837594SBarry Smith   ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr);
246712837594SBarry Smith   ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr);
24683325ff46SBarry Smith   ierr = PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
246918d89885SKarl Rupp   if (!complete_print) {
2470455a5933SJed Brown     ierr = PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL);CHKERRQ(ierr);
247118d89885SKarl Rupp     ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
247218d89885SKarl Rupp   }
247318d89885SKarl Rupp   /* for compatibility with PETSc 3.9 and older. */
2474455a5933SJed Brown   ierr = PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)");CHKERRQ(ierr);
247518d89885SKarl Rupp   ierr = PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print);CHKERRQ(ierr);
2476e885f1abSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2477e885f1abSBarry Smith   if (!test) PetscFunctionReturn(0);
2478e885f1abSBarry Smith 
2479e885f1abSBarry Smith   ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2480e885f1abSBarry Smith   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
2481e885f1abSBarry Smith   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
2482e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr);
248312837594SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n");CHKERRQ(ierr);
248412837594SBarry Smith   if (!complete_print && !directionsprinted) {
248512837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr);
2486fc35ed60SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr);
248712837594SBarry Smith   }
248812837594SBarry Smith   if (!directionsprinted) {
248912837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
2490e885f1abSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr);
249112837594SBarry Smith     directionsprinted = PETSC_TRUE;
2492e885f1abSBarry Smith   }
24933325ff46SBarry Smith   if (complete_print) {
24943325ff46SBarry Smith     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
2495e885f1abSBarry Smith   }
2496e885f1abSBarry Smith 
249712837594SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr);
249812837594SBarry Smith   if (!flg) jacobian = snes->jacobian;
249912837594SBarry Smith   else jacobian = snes->jacobian_pre;
250012837594SBarry Smith 
2501a82339d0SMatthew G. Knepley   if (!x) {
2502a82339d0SMatthew G. Knepley     ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr);
2503a82339d0SMatthew G. Knepley   } else {
2504a82339d0SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr);
2505a82339d0SMatthew G. Knepley   }
2506a82339d0SMatthew G. Knepley   if (!f) {
2507a82339d0SMatthew G. Knepley     ierr = VecDuplicate(x, &f);CHKERRQ(ierr);
2508a82339d0SMatthew G. Knepley   } else {
2509a82339d0SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr);
2510a82339d0SMatthew G. Knepley   }
2511a82339d0SMatthew G. Knepley   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2512a82339d0SMatthew G. Knepley   ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
2513a82339d0SMatthew G. Knepley   ierr = VecDestroy(&f);CHKERRQ(ierr);
25142cd624f9SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose);CHKERRQ(ierr);
251512837594SBarry Smith   while (jacobian) {
25162cd624f9SStefano Zampini     Mat JT = NULL, Jsave = NULL;
25172cd624f9SStefano Zampini 
25182cd624f9SStefano Zampini     if (istranspose) {
25192cd624f9SStefano Zampini       ierr = MatCreateTranspose(jacobian,&JT);CHKERRQ(ierr);
25202cd624f9SStefano Zampini       Jsave = jacobian;
25212cd624f9SStefano Zampini       jacobian = JT;
25222cd624f9SStefano Zampini     }
25230e276705SLisandro Dalcin     ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr);
252412837594SBarry Smith     if (flg) {
252512837594SBarry Smith       A    = jacobian;
252612837594SBarry Smith       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
252712837594SBarry Smith     } else {
25280bacdadaSStefano Zampini       ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr);
252912837594SBarry Smith     }
2530e885f1abSBarry Smith 
25310e276705SLisandro Dalcin     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
2532e885f1abSBarry Smith     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
2533e885f1abSBarry Smith     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
25340e276705SLisandro Dalcin     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
25350e276705SLisandro Dalcin     ierr = MatSetType(B,mattype);CHKERRQ(ierr);
2536e885f1abSBarry Smith     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
25370e276705SLisandro Dalcin     ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr);
2538e885f1abSBarry Smith     ierr = MatSetUp(B);CHKERRQ(ierr);
2539e885f1abSBarry Smith     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
2540e885f1abSBarry Smith 
2541e885f1abSBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
2542e885f1abSBarry Smith     ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr);
254312837594SBarry Smith 
254412837594SBarry Smith     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
254512837594SBarry Smith     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
254612837594SBarry Smith     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
2547e885f1abSBarry Smith     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
254812837594SBarry Smith     ierr = MatDestroy(&D);CHKERRQ(ierr);
254912837594SBarry Smith     if (!gnorm) gnorm = 1; /* just in case */
255012837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
255112837594SBarry Smith 
2552e885f1abSBarry Smith     if (complete_print) {
255312837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n");CHKERRQ(ierr);
25541878987eSStefano Zampini       ierr = MatView(A,mviewer);CHKERRQ(ierr);
255512837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n");CHKERRQ(ierr);
25563325ff46SBarry Smith       ierr = MatView(B,mviewer);CHKERRQ(ierr);
2557e885f1abSBarry Smith     }
2558e885f1abSBarry Smith 
2559df10fb39SFande Kong     if (threshold_print || complete_print) {
2560e885f1abSBarry Smith       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
2561e885f1abSBarry Smith       PetscScalar       *cvals;
2562e885f1abSBarry Smith       const PetscInt    *bcols;
2563e885f1abSBarry Smith       const PetscScalar *bvals;
2564e885f1abSBarry Smith 
2565e885f1abSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
25660e276705SLisandro Dalcin       ierr = MatSetType(C,mattype);CHKERRQ(ierr);
2567e885f1abSBarry Smith       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
25680e276705SLisandro Dalcin       ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr);
2569e885f1abSBarry Smith       ierr = MatSetUp(C);CHKERRQ(ierr);
2570e885f1abSBarry Smith       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
25710e276705SLisandro Dalcin 
25720e276705SLisandro Dalcin       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
2573e885f1abSBarry Smith       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
2574e885f1abSBarry Smith 
2575e885f1abSBarry Smith       for (row = Istart; row < Iend; row++) {
2576e885f1abSBarry Smith         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2577e885f1abSBarry Smith         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
2578e885f1abSBarry Smith         for (j = 0, cncols = 0; j < bncols; j++) {
257923a52b1dSBarry Smith           if (PetscAbsScalar(bvals[j]) > threshold) {
2580e885f1abSBarry Smith             ccols[cncols] = bcols[j];
2581e885f1abSBarry Smith             cvals[cncols] = bvals[j];
2582e885f1abSBarry Smith             cncols += 1;
2583e885f1abSBarry Smith           }
2584e885f1abSBarry Smith         }
2585e885f1abSBarry Smith         if (cncols) {
2586e885f1abSBarry Smith           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
2587e885f1abSBarry Smith         }
2588e885f1abSBarry Smith         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2589e885f1abSBarry Smith         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
2590e885f1abSBarry Smith       }
2591e885f1abSBarry Smith       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2592e885f1abSBarry Smith       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
259312837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
259418d89885SKarl Rupp       ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr);
2595e885f1abSBarry Smith       ierr = MatDestroy(&C);CHKERRQ(ierr);
2596e885f1abSBarry Smith     }
259712837594SBarry Smith     ierr = MatDestroy(&A);CHKERRQ(ierr);
2598e885f1abSBarry Smith     ierr = MatDestroy(&B);CHKERRQ(ierr);
25992cd624f9SStefano Zampini     ierr = MatDestroy(&JT);CHKERRQ(ierr);
26002cd624f9SStefano Zampini     if (Jsave) jacobian = Jsave;
260112837594SBarry Smith     if (jacobian != snes->jacobian_pre) {
260212837594SBarry Smith       jacobian = snes->jacobian_pre;
260312837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr);
260412837594SBarry Smith     }
260512837594SBarry Smith     else jacobian = NULL;
260612837594SBarry Smith   }
2607a82339d0SMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
26083325ff46SBarry Smith   if (complete_print) {
26093325ff46SBarry Smith     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
26103325ff46SBarry Smith   }
2611a0c90127SFande Kong   if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); }
2612e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
2613e885f1abSBarry Smith   PetscFunctionReturn(0);
2614e885f1abSBarry Smith }
2615e885f1abSBarry Smith 
261662fef451SLois Curfman McInnes /*@
2617bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
261862fef451SLois Curfman McInnes 
2619d083f849SBarry Smith    Collective on SNES
2620c7afd0dbSLois Curfman McInnes 
262162fef451SLois Curfman McInnes    Input Parameters:
2622c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2623c7afd0dbSLois Curfman McInnes -  x - input vector
262462fef451SLois Curfman McInnes 
262562fef451SLois Curfman McInnes    Output Parameters:
2626c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2627d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2628fee21e36SBarry Smith 
2629e35cf81dSBarry Smith   Options Database Keys:
2630e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2631693365a8SJed Brown .    -snes_lag_jacobian <lag>
2632455a5933SJed 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.
2633455a5933SJed 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
2634693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2635693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2636693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
26374c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
263894d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2639c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2640c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2641c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2642c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
26434c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2644c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2645c01495d3SJed Brown 
2646e35cf81dSBarry Smith 
264762fef451SLois Curfman McInnes    Notes:
264862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
264962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
265062fef451SLois Curfman McInnes 
265195452b02SPatrick Sanan    Developer Notes:
265295452b02SPatrick 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
2653e885f1abSBarry Smith       for with the SNESType of test that has been removed.
2654e885f1abSBarry Smith 
265536851e7fSLois Curfman McInnes    Level: developer
265636851e7fSLois Curfman McInnes 
2657e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
265862fef451SLois Curfman McInnes @*/
2659d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
26609b94acceSBarry Smith {
2661dfbe8321SBarry Smith   PetscErrorCode ierr;
2662ace3abfcSBarry Smith   PetscBool      flag;
26636cab3a1bSJed Brown   DM             dm;
2664942e3340SBarry Smith   DMSNES         sdm;
2665e0e3a89bSBarry Smith   KSP            ksp;
26663a40ed3dSBarry Smith 
26673a40ed3dSBarry Smith   PetscFunctionBegin;
26680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26690700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2670c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
267162796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
26726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2673942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
26743232da50SPeter Brune 
2675ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2676ebd3b9afSBarry Smith 
2677ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2678ebd3b9afSBarry Smith 
2679fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2680fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2681f5af7f23SKarl Rupp 
2682fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2683fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2684e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
268594ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2686ebd3b9afSBarry Smith     if (flag) {
268794ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
268894ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2689ebd3b9afSBarry Smith     }
2690e35cf81dSBarry Smith     PetscFunctionReturn(0);
269137ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2692e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
269394ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2694ebd3b9afSBarry Smith     if (flag) {
269594ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
269694ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2697ebd3b9afSBarry Smith     }
2698e35cf81dSBarry Smith     PetscFunctionReturn(0);
2699e35cf81dSBarry Smith   }
2700efd4aadfSBarry Smith   if (snes->npc && snes->npcside== PC_LEFT) {
270194ab13aaSBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
270294ab13aaSBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2703d728fb7dSPeter Brune     PetscFunctionReturn(0);
2704d728fb7dSPeter Brune   }
2705e35cf81dSBarry Smith 
270694ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
27078860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2708d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2709d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2710d64ed03dSBarry Smith   PetscStackPop;
27118860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
271294ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
271328d58a37SPierre Jolivet 
271428d58a37SPierre Jolivet   /* attach latest linearization point to the preconditioning matrix */
271528d58a37SPierre Jolivet   ierr = PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X);CHKERRQ(ierr);
2716a8054027SBarry Smith 
2717e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2718e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
27193b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
27203b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2721d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
27223b4f5425SBarry Smith     snes->lagpreconditioner = -1;
27233b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2724a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2725d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
272637ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2727a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2728d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2729d1e9a80fSBarry Smith   } else {
2730d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2731d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2732a8054027SBarry Smith   }
2733a8054027SBarry Smith 
2734e885f1abSBarry Smith   ierr = SNESTestJacobian(snes);CHKERRQ(ierr);
27356d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
273694ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
273794ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2738693365a8SJed Brown   {
2739693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
274016413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
274116413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
274216413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
274316413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2744693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
27450298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2746693365a8SJed Brown       PetscViewer  vdraw,vstdout;
27476b3a5b13SJed Brown       PetscBool    flg;
2748693365a8SJed Brown       if (flag_operator) {
27490bacdadaSStefano Zampini         ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr);
2750693365a8SJed Brown         Bexp = Bexp_mine;
2751693365a8SJed Brown       } else {
2752693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2753b9e7e5c1SBarry Smith         ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
275494ab13aaSBarry Smith         if (flg) Bexp = B;
2755693365a8SJed Brown         else {
2756693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
27570bacdadaSStefano Zampini           ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr);
2758693365a8SJed Brown           Bexp = Bexp_mine;
2759693365a8SJed Brown         }
2760693365a8SJed Brown       }
2761693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2762d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2763ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2764693365a8SJed Brown       if (flag_draw || flag_contour) {
27659e5d0892SLisandro Dalcin         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2766693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
27670298fd71SBarry Smith       } else vdraw = NULL;
2768693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2769693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2770693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2771693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2772693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2773693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2774693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2775693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2776693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2777693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2778693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2779693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2780693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2781693365a8SJed Brown       }
2782693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2783693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2784693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2785693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2786693365a8SJed Brown     }
2787693365a8SJed Brown   }
27884c30e9fbSJed Brown   {
27896719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
27906719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
279116413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
279216413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
279316413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
279416413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
279516413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
279627b0f280SBarry Smith     if (flag_threshold) {
2797c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2798c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
279927b0f280SBarry Smith     }
28006719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
28014c30e9fbSJed Brown       Mat            Bfd;
28024c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2803335efc43SPeter Brune       MatColoring    coloring;
28044c30e9fbSJed Brown       ISColoring     iscoloring;
28054c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
28064c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
28074c30e9fbSJed Brown       void           *funcctx;
28086719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
28094c30e9fbSJed Brown 
281094ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2811335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2812335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2813335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2814335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2815335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
28164c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2817f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2818f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
28194c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
28204c30e9fbSJed Brown 
28214c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
28220298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
28234c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
28244c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
28254c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
28264c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2827d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
28284c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
28294c30e9fbSJed Brown 
2830ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
28314c30e9fbSJed Brown       if (flag_draw || flag_contour) {
28329e5d0892SLisandro Dalcin         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
28334c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
28340298fd71SBarry Smith       } else vdraw = NULL;
28354c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
283694ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
283794ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
28384c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
28396719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
28404c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
284194ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
28424c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
28436719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
28444c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
284557622a8eSBarry Smith       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax);CHKERRQ(ierr);
28466719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
28474c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
28484c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
28494c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
28504c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
28514c30e9fbSJed Brown       }
28524c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
28536719d8e4SJed Brown 
28546719d8e4SJed Brown       if (flag_threshold) {
28556719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
285694ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
285794ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
28586719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
28596719d8e4SJed Brown           const PetscScalar *ba,*ca;
28606719d8e4SJed Brown           const PetscInt    *bj,*cj;
28616719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
28626719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
286394ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
28646719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
286594ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
28666719d8e4SJed Brown           for (j=0; j<bn; j++) {
28676719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
28686719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
28696719d8e4SJed Brown               maxentrycol = bj[j];
28706719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
28716719d8e4SJed Brown             }
28726719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
28736719d8e4SJed Brown               maxdiffcol = bj[j];
28746719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
28756719d8e4SJed Brown             }
28766719d8e4SJed Brown             if (rdiff > maxrdiff) {
28776719d8e4SJed Brown               maxrdiffcol = bj[j];
28786719d8e4SJed Brown               maxrdiff    = rdiff;
28796719d8e4SJed Brown             }
28806719d8e4SJed Brown           }
28816719d8e4SJed Brown           if (maxrdiff > 1) {
288257622a8eSBarry Smith             ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%g at %D, maxdiff=%g at %D, maxrdiff=%g at %D):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol);CHKERRQ(ierr);
28836719d8e4SJed Brown             for (j=0; j<bn; j++) {
28846719d8e4SJed Brown               PetscReal rdiff;
28856719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
28866719d8e4SJed Brown               if (rdiff > 1) {
288757622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
28886719d8e4SJed Brown               }
28896719d8e4SJed Brown             }
28906719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
28916719d8e4SJed Brown           }
289294ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
28936719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
28946719d8e4SJed Brown         }
28956719d8e4SJed Brown       }
28964c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
28974c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
28984c30e9fbSJed Brown     }
28994c30e9fbSJed Brown   }
29003a40ed3dSBarry Smith   PetscFunctionReturn(0);
29019b94acceSBarry Smith }
29029b94acceSBarry Smith 
2903bf388a1fSBarry Smith /*MC
2904411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2905bf388a1fSBarry Smith 
2906bf388a1fSBarry Smith      Synopsis:
2907411c0326SBarry Smith      #include "petscsnes.h"
2908411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2909bf388a1fSBarry Smith 
29101843f636SBarry Smith      Collective on snes
29111843f636SBarry Smith 
29121843f636SBarry Smith     Input Parameters:
29131843f636SBarry Smith +  x - input vector, the Jacobian is to be computed at this value
2914bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2915bf388a1fSBarry Smith 
29161843f636SBarry Smith     Output Parameters:
29171843f636SBarry Smith +  Amat - the matrix that defines the (approximate) Jacobian
29181843f636SBarry Smith -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
29191843f636SBarry Smith 
2920878cb397SSatish Balay    Level: intermediate
2921878cb397SSatish Balay 
2922bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2923bf388a1fSBarry Smith M*/
2924bf388a1fSBarry Smith 
29259b94acceSBarry Smith /*@C
29269b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2927044dda88SLois Curfman McInnes    location to store the matrix.
29289b94acceSBarry Smith 
2929d083f849SBarry Smith    Logically Collective on SNES
2930c7afd0dbSLois Curfman McInnes 
29319b94acceSBarry Smith    Input Parameters:
2932c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2933e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2934e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2935411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2936c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
29370298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
29389b94acceSBarry Smith 
29399b94acceSBarry Smith    Notes:
2940e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
294116913363SBarry Smith    each matrix.
294216913363SBarry Smith 
2943895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2944895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2945895c21f2SBarry Smith 
29468d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2947a8a26c1eSJed Brown    must be a MatFDColoring.
2948a8a26c1eSJed Brown 
2949c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2950c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2951c3cc8fd1SJed Brown 
295236851e7fSLois Curfman McInnes    Level: beginner
295336851e7fSLois Curfman McInnes 
2954411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2955411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
29569b94acceSBarry Smith @*/
2957d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
29589b94acceSBarry Smith {
2959dfbe8321SBarry Smith   PetscErrorCode ierr;
29606cab3a1bSJed Brown   DM             dm;
29613a7fca6bSBarry Smith 
29623a40ed3dSBarry Smith   PetscFunctionBegin;
29630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2964e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2965e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2966e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2967e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
29686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2969f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2970e5d3d808SBarry Smith   if (Amat) {
2971e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
29726bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2973f5af7f23SKarl Rupp 
2974e5d3d808SBarry Smith     snes->jacobian = Amat;
29753a7fca6bSBarry Smith   }
2976e5d3d808SBarry Smith   if (Pmat) {
2977e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
29786bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2979f5af7f23SKarl Rupp 
2980e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
29813a7fca6bSBarry Smith   }
29823a40ed3dSBarry Smith   PetscFunctionReturn(0);
29839b94acceSBarry Smith }
298462fef451SLois Curfman McInnes 
2985c2aafc4cSSatish Balay /*@C
2986b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2987b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2988b4fd4287SBarry Smith 
2989c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2990c7afd0dbSLois Curfman McInnes 
2991b4fd4287SBarry Smith    Input Parameter:
2992b4fd4287SBarry Smith .  snes - the nonlinear solver context
2993b4fd4287SBarry Smith 
2994b4fd4287SBarry Smith    Output Parameters:
2995e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2996e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2997411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
29980298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
2999fee21e36SBarry Smith 
300036851e7fSLois Curfman McInnes    Level: advanced
300136851e7fSLois Curfman McInnes 
3002411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
3003b4fd4287SBarry Smith @*/
3004d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
3005b4fd4287SBarry Smith {
30066cab3a1bSJed Brown   PetscErrorCode ierr;
30076cab3a1bSJed Brown   DM             dm;
3008942e3340SBarry Smith   DMSNES         sdm;
30096cab3a1bSJed Brown 
30103a40ed3dSBarry Smith   PetscFunctionBegin;
30110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3012e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
3013e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
30146cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3015942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
3016f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
30176cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
30183a40ed3dSBarry Smith   PetscFunctionReturn(0);
3019b4fd4287SBarry Smith }
3020b4fd4287SBarry Smith 
302158b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
302258b371f3SBarry Smith {
302358b371f3SBarry Smith   PetscErrorCode ierr;
302458b371f3SBarry Smith   DM             dm;
302558b371f3SBarry Smith   DMSNES         sdm;
302658b371f3SBarry Smith 
302758b371f3SBarry Smith   PetscFunctionBegin;
302858b371f3SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
302958b371f3SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
303058b371f3SBarry Smith   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
303158b371f3SBarry Smith     DM        dm;
303258b371f3SBarry Smith     PetscBool isdense,ismf;
303358b371f3SBarry Smith 
303458b371f3SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
303558b371f3SBarry Smith     ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL);CHKERRQ(ierr);
303658b371f3SBarry Smith     ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL);CHKERRQ(ierr);
303758b371f3SBarry Smith     if (isdense) {
303858b371f3SBarry Smith       ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr);
303958b371f3SBarry Smith     } else if (!ismf) {
304058b371f3SBarry Smith       ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
304158b371f3SBarry Smith     }
304258b371f3SBarry Smith   }
304358b371f3SBarry Smith   PetscFunctionReturn(0);
304458b371f3SBarry Smith }
304558b371f3SBarry Smith 
30469b94acceSBarry Smith /*@
30479b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
3048272ac6f2SLois Curfman McInnes    of a nonlinear solver.
30499b94acceSBarry Smith 
3050fee21e36SBarry Smith    Collective on SNES
3051fee21e36SBarry Smith 
3052c7afd0dbSLois Curfman McInnes    Input Parameters:
305370e92668SMatthew Knepley .  snes - the SNES context
3054c7afd0dbSLois Curfman McInnes 
3055272ac6f2SLois Curfman McInnes    Notes:
3056272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
3057272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
3058272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
3059272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
3060272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
3061272ac6f2SLois Curfman McInnes 
306236851e7fSLois Curfman McInnes    Level: advanced
306336851e7fSLois Curfman McInnes 
30649b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
30659b94acceSBarry Smith @*/
30667087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
30679b94acceSBarry Smith {
3068dfbe8321SBarry Smith   PetscErrorCode ierr;
30696cab3a1bSJed Brown   DM             dm;
3070942e3340SBarry Smith   DMSNES         sdm;
3071c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
30726e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
30736b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
30746b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
30756e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
30766e2a1849SPeter Brune   Vec            f,fpc;
30776e2a1849SPeter Brune   void           *funcctx;
3078d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
30791eb13d49SPeter Brune   void           *jacctx,*appctx;
308032b97717SPeter Brune   Mat            j,jpre;
30813a40ed3dSBarry Smith 
30823a40ed3dSBarry Smith   PetscFunctionBegin;
30830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30844dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
3085e3ed9ee7SBarry Smith   ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr);
30869b94acceSBarry Smith 
30877adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
308804d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
308985385478SLisandro Dalcin   }
309085385478SLisandro Dalcin 
30910298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
309258c9b817SLisandro Dalcin 
30936cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3094942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
3095ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
309658b371f3SBarry Smith   ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr);
309758b371f3SBarry Smith 
30986cab3a1bSJed Brown   if (!snes->vec_func) {
30996cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
3100214df951SJed Brown   }
3101efd51863SBarry Smith 
310222d28d08SBarry Smith   if (!snes->ksp) {
310322d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
310422d28d08SBarry Smith   }
3105b710008aSBarry Smith 
3106d8d34be6SBarry Smith   if (snes->linesearch) {
31077601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
3108ed07d7d7SPeter Brune     ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
3109d8d34be6SBarry Smith   }
31109e764e56SPeter Brune 
3111efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
3112172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
3113172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
3114172a4300SPeter Brune   }
3115d8f46077SPeter Brune 
3116efd4aadfSBarry Smith   if (snes->npc) {
31176e2a1849SPeter Brune     /* copy the DM over */
31186e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3119efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr);
31206e2a1849SPeter Brune 
31216e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
31226e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
3123efd4aadfSBarry Smith     ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr);
312432b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
3125efd4aadfSBarry Smith     ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr);
31261eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
3127efd4aadfSBarry Smith     ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr);
31286e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
31296e2a1849SPeter Brune 
31306e2a1849SPeter Brune     /* copy the function pointers over */
3131efd4aadfSBarry Smith     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
31326e2a1849SPeter Brune 
31336e2a1849SPeter Brune     /* default to 1 iteration */
3134efd4aadfSBarry Smith     ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr);
3135efd4aadfSBarry Smith     if (snes->npcside==PC_RIGHT) {
3136efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
3137a9936a0cSPeter Brune     } else {
3138efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr);
3139a9936a0cSPeter Brune     }
3140efd4aadfSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
31416e2a1849SPeter Brune 
31426e2a1849SPeter Brune     /* copy the line search context over */
3143d8d34be6SBarry Smith     if (snes->linesearch && snes->npc->linesearch) {
31447601faf0SJed Brown       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
3145efd4aadfSBarry Smith       ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr);
31466b2b7091SBarry Smith       ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
31476b2b7091SBarry Smith       ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
31486b2b7091SBarry Smith       ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
31496b2b7091SBarry Smith       ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
31506e2a1849SPeter Brune       ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
31516e2a1849SPeter Brune     }
3152d8d34be6SBarry Smith   }
315332b97717SPeter Brune   if (snes->mf) {
315432b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
315532b97717SPeter Brune   }
315632b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
315732b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
315832b97717SPeter Brune   }
31596e2a1849SPeter Brune 
316037ec4e1aSPeter Brune   snes->jac_iter = 0;
316137ec4e1aSPeter Brune   snes->pre_iter = 0;
316237ec4e1aSPeter Brune 
3163410397dcSLisandro Dalcin   if (snes->ops->setup) {
3164410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
3165410397dcSLisandro Dalcin   }
316658c9b817SLisandro Dalcin 
316758b371f3SBarry Smith   ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr);
316858b371f3SBarry Smith 
3169efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
31706c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3171d8d34be6SBarry Smith       if (snes->linesearch){
317255d4788fSPeter Brune         ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
3173be95d8f1SBarry Smith         ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
31746c67d002SPeter Brune       }
31756c67d002SPeter Brune     }
3176d8d34be6SBarry Smith   }
3177e3ed9ee7SBarry Smith   ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr);
31787aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
31793a40ed3dSBarry Smith   PetscFunctionReturn(0);
31809b94acceSBarry Smith }
31819b94acceSBarry Smith 
318237596af1SLisandro Dalcin /*@
318337596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
318437596af1SLisandro Dalcin 
318537596af1SLisandro Dalcin    Collective on SNES
318637596af1SLisandro Dalcin 
318737596af1SLisandro Dalcin    Input Parameter:
318837596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
318937596af1SLisandro Dalcin 
3190d25893d9SBarry Smith    Level: intermediate
3191d25893d9SBarry Smith 
319295452b02SPatrick Sanan    Notes:
319395452b02SPatrick Sanan     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
319437596af1SLisandro Dalcin 
319537596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
319637596af1SLisandro Dalcin @*/
319737596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
319837596af1SLisandro Dalcin {
319937596af1SLisandro Dalcin   PetscErrorCode ierr;
320037596af1SLisandro Dalcin 
320137596af1SLisandro Dalcin   PetscFunctionBegin;
320237596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3203d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
3204d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
32050298fd71SBarry Smith     snes->user = NULL;
3206d25893d9SBarry Smith   }
3207efd4aadfSBarry Smith   if (snes->npc) {
3208efd4aadfSBarry Smith     ierr = SNESReset(snes->npc);CHKERRQ(ierr);
32098a23116dSBarry Smith   }
32108a23116dSBarry Smith 
321137596af1SLisandro Dalcin   if (snes->ops->reset) {
321237596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
321337596af1SLisandro Dalcin   }
32149e764e56SPeter Brune   if (snes->ksp) {
32159e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
32169e764e56SPeter Brune   }
32179e764e56SPeter Brune 
32189e764e56SPeter Brune   if (snes->linesearch) {
3219f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
32209e764e56SPeter Brune   }
32219e764e56SPeter Brune 
32226bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
32236bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
32246bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
32256bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
32266bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
32276bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
3228c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
3229c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
3230f5af7f23SKarl Rupp 
323140fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
323240fdac6aSLawrence Mitchell 
323337596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
323437596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
323537596af1SLisandro Dalcin   PetscFunctionReturn(0);
323637596af1SLisandro Dalcin }
323737596af1SLisandro Dalcin 
323852baeb72SSatish Balay /*@
3239c4421ceaSFande Kong    SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object.
3240c4421ceaSFande Kong 
3241c4421ceaSFande Kong    Collective on SNES
3242c4421ceaSFande Kong 
3243c4421ceaSFande Kong    Input Parameter:
3244c4421ceaSFande Kong .  snes - iterative context obtained from SNESCreate()
3245c4421ceaSFande Kong 
3246c4421ceaSFande Kong    Level: intermediate
3247c4421ceaSFande Kong 
3248c4421ceaSFande Kong .seealso: SNESCreate(), SNESDestroy(), SNESReset()
3249c4421ceaSFande Kong @*/
3250c4421ceaSFande Kong PetscErrorCode  SNESConvergedReasonViewCancel(SNES snes)
3251c4421ceaSFande Kong {
3252c4421ceaSFande Kong   PetscErrorCode ierr;
3253c4421ceaSFande Kong   PetscInt       i;
3254c4421ceaSFande Kong 
3255c4421ceaSFande Kong   PetscFunctionBegin;
3256c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3257c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews; i++) {
3258c4421ceaSFande Kong     if (snes->reasonviewdestroy[i]) {
3259c4421ceaSFande Kong       ierr = (*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i]);CHKERRQ(ierr);
3260c4421ceaSFande Kong     }
3261c4421ceaSFande Kong   }
3262c4421ceaSFande Kong   snes->numberreasonviews = 0;
3263c4421ceaSFande Kong   PetscFunctionReturn(0);
3264c4421ceaSFande Kong }
3265c4421ceaSFande Kong 
3266c4421ceaSFande Kong /*@
32679b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
32689b94acceSBarry Smith    with SNESCreate().
32699b94acceSBarry Smith 
3270c7afd0dbSLois Curfman McInnes    Collective on SNES
3271c7afd0dbSLois Curfman McInnes 
32729b94acceSBarry Smith    Input Parameter:
32739b94acceSBarry Smith .  snes - the SNES context
32749b94acceSBarry Smith 
327536851e7fSLois Curfman McInnes    Level: beginner
327636851e7fSLois Curfman McInnes 
327763a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
32789b94acceSBarry Smith @*/
32796bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
32809b94acceSBarry Smith {
32816849ba73SBarry Smith   PetscErrorCode ierr;
32823a40ed3dSBarry Smith 
32833a40ed3dSBarry Smith   PetscFunctionBegin;
32846bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
32856bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
32869e5d0892SLisandro Dalcin   if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);}
3287d4bb536fSBarry Smith 
32886bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
3289efd4aadfSBarry Smith   ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr);
32906b8b9a38SLisandro Dalcin 
3291e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
3292e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
32936bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
32946d4c513bSLisandro Dalcin 
329533124788SMatthew G. Knepley   if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);}
32966bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
32976bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
3298f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
32996b8b9a38SLisandro Dalcin 
33006bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
33016bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
33026bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
33036b8b9a38SLisandro Dalcin   }
3304071fcb05SBarry Smith   if ((*snes)->conv_hist_alloc) {
3305071fcb05SBarry Smith     ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr);
330658c9b817SLisandro Dalcin   }
33076bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
3308c4421ceaSFande Kong   ierr = SNESConvergedReasonViewCancel((*snes));CHKERRQ(ierr);
3309a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
33103a40ed3dSBarry Smith   PetscFunctionReturn(0);
33119b94acceSBarry Smith }
33129b94acceSBarry Smith 
33139b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
33149b94acceSBarry Smith 
3315a8054027SBarry Smith /*@
3316a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3317a8054027SBarry Smith 
33183f9fe445SBarry Smith    Logically Collective on SNES
3319a8054027SBarry Smith 
3320a8054027SBarry Smith    Input Parameters:
3321a8054027SBarry Smith +  snes - the SNES context
3322d8e291bfSBarry Smith -  lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
33233b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3324a8054027SBarry Smith 
3325a8054027SBarry Smith    Options Database Keys:
33263d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
33273d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
33283d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
33293d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3330a8054027SBarry Smith 
3331a8054027SBarry Smith    Notes:
3332a8054027SBarry Smith    The default is 1
33333d5a8a6aSBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called
3334d8e291bfSBarry Smith 
3335d8e291bfSBarry Smith    SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves.
3336a8054027SBarry Smith 
3337a8054027SBarry Smith    Level: intermediate
3338a8054027SBarry Smith 
33393d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(),
33403d5a8a6aSBarry Smith           SNESSetLagJacobianPersists()
3341a8054027SBarry Smith 
3342a8054027SBarry Smith @*/
33437087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
3344a8054027SBarry Smith {
3345a8054027SBarry Smith   PetscFunctionBegin;
33460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3347e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3348e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3349c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3350a8054027SBarry Smith   snes->lagpreconditioner = lag;
3351a8054027SBarry Smith   PetscFunctionReturn(0);
3352a8054027SBarry Smith }
3353a8054027SBarry Smith 
3354efd51863SBarry Smith /*@
3355efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
3356efd51863SBarry Smith 
3357efd51863SBarry Smith    Logically Collective on SNES
3358efd51863SBarry Smith 
3359efd51863SBarry Smith    Input Parameters:
3360efd51863SBarry Smith +  snes - the SNES context
3361efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
3362efd51863SBarry Smith 
3363efd51863SBarry Smith    Options Database Keys:
3364efd51863SBarry Smith .    -snes_grid_sequence <steps>
3365efd51863SBarry Smith 
3366efd51863SBarry Smith    Level: intermediate
3367efd51863SBarry Smith 
3368c0df2a02SJed Brown    Notes:
3369c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3370c0df2a02SJed Brown 
3371fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
3372efd51863SBarry Smith 
3373efd51863SBarry Smith @*/
3374efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
3375efd51863SBarry Smith {
3376efd51863SBarry Smith   PetscFunctionBegin;
3377efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3378efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
3379efd51863SBarry Smith   snes->gridsequence = steps;
3380efd51863SBarry Smith   PetscFunctionReturn(0);
3381efd51863SBarry Smith }
3382efd51863SBarry Smith 
3383fa19ca70SBarry Smith /*@
3384fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
3385fa19ca70SBarry Smith 
3386fa19ca70SBarry Smith    Logically Collective on SNES
3387fa19ca70SBarry Smith 
3388fa19ca70SBarry Smith    Input Parameter:
3389fa19ca70SBarry Smith .  snes - the SNES context
3390fa19ca70SBarry Smith 
3391fa19ca70SBarry Smith    Output Parameter:
3392fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
3393fa19ca70SBarry Smith 
3394fa19ca70SBarry Smith    Options Database Keys:
3395fa19ca70SBarry Smith .    -snes_grid_sequence <steps>
3396fa19ca70SBarry Smith 
3397fa19ca70SBarry Smith    Level: intermediate
3398fa19ca70SBarry Smith 
3399fa19ca70SBarry Smith    Notes:
3400fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3401fa19ca70SBarry Smith 
3402fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
3403fa19ca70SBarry Smith 
3404fa19ca70SBarry Smith @*/
3405fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3406fa19ca70SBarry Smith {
3407fa19ca70SBarry Smith   PetscFunctionBegin;
3408fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3409fa19ca70SBarry Smith   *steps = snes->gridsequence;
3410fa19ca70SBarry Smith   PetscFunctionReturn(0);
3411fa19ca70SBarry Smith }
3412fa19ca70SBarry Smith 
3413a8054027SBarry Smith /*@
3414a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3415a8054027SBarry Smith 
34163f9fe445SBarry Smith    Not Collective
3417a8054027SBarry Smith 
3418a8054027SBarry Smith    Input Parameter:
3419a8054027SBarry Smith .  snes - the SNES context
3420a8054027SBarry Smith 
3421a8054027SBarry Smith    Output Parameter:
3422a8054027SBarry 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
34233b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3424a8054027SBarry Smith 
3425a8054027SBarry Smith    Options Database Keys:
34263d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34273d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34283d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34293d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3430a8054027SBarry Smith 
3431a8054027SBarry Smith    Notes:
3432a8054027SBarry Smith    The default is 1
3433a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3434a8054027SBarry Smith 
3435a8054027SBarry Smith    Level: intermediate
3436a8054027SBarry Smith 
34373d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3438a8054027SBarry Smith 
3439a8054027SBarry Smith @*/
34407087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3441a8054027SBarry Smith {
3442a8054027SBarry Smith   PetscFunctionBegin;
34430700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3444a8054027SBarry Smith   *lag = snes->lagpreconditioner;
3445a8054027SBarry Smith   PetscFunctionReturn(0);
3446a8054027SBarry Smith }
3447a8054027SBarry Smith 
3448e35cf81dSBarry Smith /*@
3449e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3450e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3451e35cf81dSBarry Smith 
34523f9fe445SBarry Smith    Logically Collective on SNES
3453e35cf81dSBarry Smith 
3454e35cf81dSBarry Smith    Input Parameters:
3455e35cf81dSBarry Smith +  snes - the SNES context
3456e35cf81dSBarry 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
3457fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3458e35cf81dSBarry Smith 
3459e35cf81dSBarry Smith    Options Database Keys:
34603d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34613d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34623d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34633d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag.
3464e35cf81dSBarry Smith 
3465e35cf81dSBarry Smith    Notes:
3466e35cf81dSBarry Smith    The default is 1
3467e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3468fe3ffe1eSBarry 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
3469fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3470e35cf81dSBarry Smith 
3471e35cf81dSBarry Smith    Level: intermediate
3472e35cf81dSBarry Smith 
34733d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3474e35cf81dSBarry Smith 
3475e35cf81dSBarry Smith @*/
34767087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3477e35cf81dSBarry Smith {
3478e35cf81dSBarry Smith   PetscFunctionBegin;
34790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3480e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3481e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3482c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3483e35cf81dSBarry Smith   snes->lagjacobian = lag;
3484e35cf81dSBarry Smith   PetscFunctionReturn(0);
3485e35cf81dSBarry Smith }
3486e35cf81dSBarry Smith 
3487e35cf81dSBarry Smith /*@
3488e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3489e35cf81dSBarry Smith 
34903f9fe445SBarry Smith    Not Collective
3491e35cf81dSBarry Smith 
3492e35cf81dSBarry Smith    Input Parameter:
3493e35cf81dSBarry Smith .  snes - the SNES context
3494e35cf81dSBarry Smith 
3495e35cf81dSBarry Smith    Output Parameter:
3496e35cf81dSBarry 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
3497e35cf81dSBarry Smith          the Jacobian is built etc.
3498e35cf81dSBarry Smith 
3499e35cf81dSBarry Smith    Notes:
3500e35cf81dSBarry Smith    The default is 1
35013d5a8a6aSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called.
3502e35cf81dSBarry Smith 
3503e35cf81dSBarry Smith    Level: intermediate
3504e35cf81dSBarry Smith 
35053d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3506e35cf81dSBarry Smith 
3507e35cf81dSBarry Smith @*/
35087087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3509e35cf81dSBarry Smith {
3510e35cf81dSBarry Smith   PetscFunctionBegin;
35110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3512e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3513e35cf81dSBarry Smith   PetscFunctionReturn(0);
3514e35cf81dSBarry Smith }
3515e35cf81dSBarry Smith 
351637ec4e1aSPeter Brune /*@
351737ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
351837ec4e1aSPeter Brune 
351937ec4e1aSPeter Brune    Logically collective on SNES
352037ec4e1aSPeter Brune 
352137ec4e1aSPeter Brune    Input Parameter:
352237ec4e1aSPeter Brune +  snes - the SNES context
35239d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
352437ec4e1aSPeter Brune 
352537ec4e1aSPeter Brune    Options Database Keys:
35263d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35273d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35283d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35293d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
35303d5a8a6aSBarry Smith 
353137ec4e1aSPeter Brune 
353295452b02SPatrick Sanan    Notes:
353395452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
353437ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
353537ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
353637ec4e1aSPeter Brune 
353737ec4e1aSPeter Brune    Level: developer
353837ec4e1aSPeter Brune 
35393d5a8a6aSBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagJacobianPersists()
354037ec4e1aSPeter Brune 
354137ec4e1aSPeter Brune @*/
354237ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
354337ec4e1aSPeter Brune {
354437ec4e1aSPeter Brune   PetscFunctionBegin;
354537ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
354637ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
354737ec4e1aSPeter Brune   snes->lagjac_persist = flg;
354837ec4e1aSPeter Brune   PetscFunctionReturn(0);
354937ec4e1aSPeter Brune }
355037ec4e1aSPeter Brune 
355137ec4e1aSPeter Brune /*@
3552d8e291bfSBarry Smith    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves
355337ec4e1aSPeter Brune 
355437ec4e1aSPeter Brune    Logically Collective on SNES
355537ec4e1aSPeter Brune 
355637ec4e1aSPeter Brune    Input Parameter:
355737ec4e1aSPeter Brune +  snes - the SNES context
35589d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
355937ec4e1aSPeter Brune 
356037ec4e1aSPeter Brune    Options Database Keys:
35613d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35623d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35633d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35643d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
356537ec4e1aSPeter Brune 
356695452b02SPatrick Sanan    Notes:
356795452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
356837ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
356937ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
357037ec4e1aSPeter Brune 
357137ec4e1aSPeter Brune    Level: developer
357237ec4e1aSPeter Brune 
35733d5a8a6aSBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagPreconditioner()
357437ec4e1aSPeter Brune 
357537ec4e1aSPeter Brune @*/
357637ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
357737ec4e1aSPeter Brune {
357837ec4e1aSPeter Brune   PetscFunctionBegin;
357937ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
358037ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
358137ec4e1aSPeter Brune   snes->lagpre_persist = flg;
358237ec4e1aSPeter Brune   PetscFunctionReturn(0);
358337ec4e1aSPeter Brune }
358437ec4e1aSPeter Brune 
35859b94acceSBarry Smith /*@
3586be5caee7SBarry Smith    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm
3587be5caee7SBarry Smith 
3588be5caee7SBarry Smith    Logically Collective on SNES
3589be5caee7SBarry Smith 
3590be5caee7SBarry Smith    Input Parameters:
3591be5caee7SBarry Smith +  snes - the SNES context
3592be5caee7SBarry Smith -  force - PETSC_TRUE require at least one iteration
3593be5caee7SBarry Smith 
3594be5caee7SBarry Smith    Options Database Keys:
3595be5caee7SBarry Smith .    -snes_force_iteration <force> - Sets forcing an iteration
3596be5caee7SBarry Smith 
3597be5caee7SBarry Smith    Notes:
3598be5caee7SBarry Smith    This is used sometimes with TS to prevent TS from detecting a false steady state solution
3599be5caee7SBarry Smith 
3600be5caee7SBarry Smith    Level: intermediate
3601be5caee7SBarry Smith 
3602be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
3603be5caee7SBarry Smith @*/
3604be5caee7SBarry Smith PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
3605be5caee7SBarry Smith {
3606be5caee7SBarry Smith   PetscFunctionBegin;
3607be5caee7SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3608be5caee7SBarry Smith   snes->forceiteration = force;
3609be5caee7SBarry Smith   PetscFunctionReturn(0);
3610be5caee7SBarry Smith }
3611be5caee7SBarry Smith 
361285216dc7SFande Kong /*@
361385216dc7SFande Kong    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm
361485216dc7SFande Kong 
361585216dc7SFande Kong    Logically Collective on SNES
361685216dc7SFande Kong 
361785216dc7SFande Kong    Input Parameters:
361885216dc7SFande Kong .  snes - the SNES context
361985216dc7SFande Kong 
362085216dc7SFande Kong    Output Parameter:
362185216dc7SFande Kong .  force - PETSC_TRUE requires at least one iteration.
362285216dc7SFande Kong 
362306dd6b0eSSatish Balay    Level: intermediate
362406dd6b0eSSatish Balay 
362585216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
362685216dc7SFande Kong @*/
362785216dc7SFande Kong PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
362885216dc7SFande Kong {
362985216dc7SFande Kong   PetscFunctionBegin;
363085216dc7SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
363185216dc7SFande Kong   *force = snes->forceiteration;
363285216dc7SFande Kong   PetscFunctionReturn(0);
363385216dc7SFande Kong }
3634be5caee7SBarry Smith 
3635be5caee7SBarry Smith /*@
3636d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
36379b94acceSBarry Smith 
36383f9fe445SBarry Smith    Logically Collective on SNES
3639c7afd0dbSLois Curfman McInnes 
36409b94acceSBarry Smith    Input Parameters:
3641c7afd0dbSLois Curfman McInnes +  snes - the SNES context
364270441072SBarry Smith .  abstol - absolute convergence tolerance
364333174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
36445358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
364533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3646e71169deSBarry Smith -  maxf - maximum number of function evaluations (-1 indicates no limit)
3647fee21e36SBarry Smith 
364833174efeSLois Curfman McInnes    Options Database Keys:
364970441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3650c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3651c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3652c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3653c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
36549b94acceSBarry Smith 
3655d7a720efSLois Curfman McInnes    Notes:
36569b94acceSBarry Smith    The default maximum number of iterations is 50.
36579b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
36589b94acceSBarry Smith 
365936851e7fSLois Curfman McInnes    Level: intermediate
366036851e7fSLois Curfman McInnes 
3661be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration()
36629b94acceSBarry Smith @*/
36637087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
36649b94acceSBarry Smith {
36653a40ed3dSBarry Smith   PetscFunctionBegin;
36660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3667c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3668c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3669c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3670c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3671c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3672c5eb9154SBarry Smith 
3673ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
367457622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3675ab54825eSJed Brown     snes->abstol = abstol;
3676ab54825eSJed Brown   }
3677ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
367857622a8eSBarry Smith     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol);
3679ab54825eSJed Brown     snes->rtol = rtol;
3680ab54825eSJed Brown   }
3681ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
368257622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3683c60f73f4SPeter Brune     snes->stol = stol;
3684ab54825eSJed Brown   }
3685ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3686ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3687ab54825eSJed Brown     snes->max_its = maxit;
3688ab54825eSJed Brown   }
3689ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3690e71169deSBarry Smith     if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf);
3691ab54825eSJed Brown     snes->max_funcs = maxf;
3692ab54825eSJed Brown   }
369388976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
36943a40ed3dSBarry Smith   PetscFunctionReturn(0);
36959b94acceSBarry Smith }
36969b94acceSBarry Smith 
3697e4d06f11SPatrick Farrell /*@
3698e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3699e4d06f11SPatrick Farrell 
3700e4d06f11SPatrick Farrell    Logically Collective on SNES
3701e4d06f11SPatrick Farrell 
3702e4d06f11SPatrick Farrell    Input Parameters:
3703e4d06f11SPatrick Farrell +  snes - the SNES context
3704e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3705e4d06f11SPatrick Farrell 
3706e4d06f11SPatrick Farrell    Options Database Keys:
3707a2b725a8SWilliam Gropp .    -snes_divergence_tolerance <divtol> - Sets divtol
3708e4d06f11SPatrick Farrell 
3709e4d06f11SPatrick Farrell    Notes:
3710e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3711e4d06f11SPatrick Farrell 
3712e4d06f11SPatrick Farrell    Level: intermediate
3713e4d06f11SPatrick Farrell 
3714e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
3715e4d06f11SPatrick Farrell @*/
3716e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3717e4d06f11SPatrick Farrell {
3718e4d06f11SPatrick Farrell   PetscFunctionBegin;
3719e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3720e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3721e4d06f11SPatrick Farrell 
3722e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3723e4d06f11SPatrick Farrell     snes->divtol = divtol;
3724e4d06f11SPatrick Farrell   }
3725e4d06f11SPatrick Farrell   else {
3726e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3727e4d06f11SPatrick Farrell   }
3728e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3729e4d06f11SPatrick Farrell }
3730e4d06f11SPatrick Farrell 
37319b94acceSBarry Smith /*@
373233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
373333174efeSLois Curfman McInnes 
3734c7afd0dbSLois Curfman McInnes    Not Collective
3735c7afd0dbSLois Curfman McInnes 
373633174efeSLois Curfman McInnes    Input Parameters:
3737c7afd0dbSLois Curfman McInnes +  snes - the SNES context
373885385478SLisandro Dalcin .  atol - absolute convergence tolerance
373933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
374033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
374133174efeSLois Curfman McInnes            of the change in the solution between steps
374233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3743c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3744fee21e36SBarry Smith 
374533174efeSLois Curfman McInnes    Notes:
37460298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
374733174efeSLois Curfman McInnes 
374836851e7fSLois Curfman McInnes    Level: intermediate
374936851e7fSLois Curfman McInnes 
375033174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
375133174efeSLois Curfman McInnes @*/
37527087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
375333174efeSLois Curfman McInnes {
37543a40ed3dSBarry Smith   PetscFunctionBegin;
37550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
375685385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
375733174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3758c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
375933174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
376033174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
37613a40ed3dSBarry Smith   PetscFunctionReturn(0);
376233174efeSLois Curfman McInnes }
376333174efeSLois Curfman McInnes 
3764e4d06f11SPatrick Farrell /*@
3765e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3766e4d06f11SPatrick Farrell 
3767e4d06f11SPatrick Farrell    Not Collective
3768e4d06f11SPatrick Farrell 
3769e4d06f11SPatrick Farrell    Input Parameters:
3770e4d06f11SPatrick Farrell +  snes - the SNES context
3771e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3772e4d06f11SPatrick Farrell 
3773e4d06f11SPatrick Farrell    Level: intermediate
3774e4d06f11SPatrick Farrell 
3775e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance()
3776e4d06f11SPatrick Farrell @*/
3777e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3778e4d06f11SPatrick Farrell {
3779e4d06f11SPatrick Farrell   PetscFunctionBegin;
3780e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3781e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3782e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3783e4d06f11SPatrick Farrell }
3784e4d06f11SPatrick Farrell 
378533174efeSLois Curfman McInnes /*@
37869b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
37879b94acceSBarry Smith 
37883f9fe445SBarry Smith    Logically Collective on SNES
3789fee21e36SBarry Smith 
3790c7afd0dbSLois Curfman McInnes    Input Parameters:
3791c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3792c7afd0dbSLois Curfman McInnes -  tol - tolerance
3793c7afd0dbSLois Curfman McInnes 
37949b94acceSBarry Smith    Options Database Key:
3795c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
37969b94acceSBarry Smith 
379736851e7fSLois Curfman McInnes    Level: intermediate
379836851e7fSLois Curfman McInnes 
37992492ecdbSBarry Smith .seealso: SNESSetTolerances()
38009b94acceSBarry Smith @*/
38017087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
38029b94acceSBarry Smith {
38033a40ed3dSBarry Smith   PetscFunctionBegin;
38040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3805c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
38069b94acceSBarry Smith   snes->deltatol = tol;
38073a40ed3dSBarry Smith   PetscFunctionReturn(0);
38089b94acceSBarry Smith }
38099b94acceSBarry Smith 
38106ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
38116ba87a44SLisandro Dalcin 
38127087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3813b271bb04SBarry Smith {
3814b271bb04SBarry Smith   PetscDrawLG      lg;
3815b271bb04SBarry Smith   PetscErrorCode   ierr;
3816b271bb04SBarry Smith   PetscReal        x,y,per;
3817b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3818b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3819b271bb04SBarry Smith   PetscDraw        draw;
3820b271bb04SBarry Smith 
3821459f5d12SBarry Smith   PetscFunctionBegin;
38224d4332d5SBarry Smith   PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4);
3823b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3824b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3825b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3826b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3827b271bb04SBarry Smith   x    = (PetscReal)n;
382877b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
382994c9c6d3SKarl Rupp   else y = -15.0;
3830b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
38316934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3832b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
38336934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3834b271bb04SBarry Smith   }
3835b271bb04SBarry Smith 
3836b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3837b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3838b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3839b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3840b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3841b271bb04SBarry Smith   x    = (PetscReal)n;
3842b271bb04SBarry Smith   y    = 100.0*per;
3843b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
38446934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3845b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
38466934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3847b271bb04SBarry Smith   }
3848b271bb04SBarry Smith 
3849b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3850b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3851b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3852b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3853b271bb04SBarry Smith   x    = (PetscReal)n;
3854b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
3855b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
38566934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3857b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
38586934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3859b271bb04SBarry Smith   }
3860b271bb04SBarry Smith 
3861b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3862b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3863b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3864b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3865b271bb04SBarry Smith   x    = (PetscReal)n;
3866b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
3867b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3868b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3869b271bb04SBarry Smith   }
38706934998bSLisandro Dalcin   if (n < 20 || !(n % 5) || snes->reason) {
3871b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
38726934998bSLisandro Dalcin     ierr = PetscDrawLGSave(lg);CHKERRQ(ierr);
3873b271bb04SBarry Smith   }
3874b271bb04SBarry Smith   prev = rnorm;
3875b271bb04SBarry Smith   PetscFunctionReturn(0);
3876b271bb04SBarry Smith }
3877b271bb04SBarry Smith 
3878228d79bcSJed Brown /*@
3879228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3880228d79bcSJed Brown 
3881228d79bcSJed Brown    Collective on SNES
3882228d79bcSJed Brown 
3883228d79bcSJed Brown    Input Parameters:
3884228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3885228d79bcSJed Brown .  iter - iteration number
3886228d79bcSJed Brown -  rnorm - relative norm of the residual
3887228d79bcSJed Brown 
3888228d79bcSJed Brown    Notes:
3889228d79bcSJed Brown    This routine is called by the SNES implementations.
3890228d79bcSJed Brown    It does not typically need to be called by the user.
3891228d79bcSJed Brown 
3892228d79bcSJed Brown    Level: developer
3893228d79bcSJed Brown 
3894228d79bcSJed Brown .seealso: SNESMonitorSet()
3895228d79bcSJed Brown @*/
38967a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
38977a03ce2fSLisandro Dalcin {
38987a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
38997a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
39007a03ce2fSLisandro Dalcin 
39017a03ce2fSLisandro Dalcin   PetscFunctionBegin;
39028860a134SJunchao Zhang   ierr = VecLockReadPush(snes->vec_sol);CHKERRQ(ierr);
39037a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
39047a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
39057a03ce2fSLisandro Dalcin   }
39068860a134SJunchao Zhang   ierr = VecLockReadPop(snes->vec_sol);CHKERRQ(ierr);
39077a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
39087a03ce2fSLisandro Dalcin }
39097a03ce2fSLisandro Dalcin 
39109b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
39119b94acceSBarry Smith 
3912bf388a1fSBarry Smith /*MC
3913bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3914bf388a1fSBarry Smith 
3915bf388a1fSBarry Smith      Synopsis:
3916aaa7dc30SBarry Smith      #include <petscsnes.h>
3917bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3918bf388a1fSBarry Smith 
39191843f636SBarry Smith      Collective on snes
39201843f636SBarry Smith 
39211843f636SBarry Smith     Input Parameters:
3922bf388a1fSBarry Smith +    snes - the SNES context
3923bf388a1fSBarry Smith .    its - iteration number
3924bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3925bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3926bf388a1fSBarry Smith 
3927878cb397SSatish Balay    Level: advanced
3928878cb397SSatish Balay 
3929bf388a1fSBarry Smith .seealso:   SNESMonitorSet(), SNESMonitorGet()
3930bf388a1fSBarry Smith M*/
3931bf388a1fSBarry Smith 
39329b94acceSBarry Smith /*@C
3933a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
39349b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
39359b94acceSBarry Smith    progress.
39369b94acceSBarry Smith 
39373f9fe445SBarry Smith    Logically Collective on SNES
3938fee21e36SBarry Smith 
3939c7afd0dbSLois Curfman McInnes    Input Parameters:
3940c7afd0dbSLois Curfman McInnes +  snes - the SNES context
39416e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3942b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
39430298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3944b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
39450298fd71SBarry Smith           (may be NULL)
39469b94acceSBarry Smith 
39479665c990SLois Curfman McInnes    Options Database Keys:
3948a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
3949798534f6SMatthew G. Knepley .    -snes_monitor draw::draw_lg - sets line graph monitor,
3950cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3951c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3952a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3953c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3954c7afd0dbSLois Curfman McInnes                             the options database.
39559665c990SLois Curfman McInnes 
3956639f9d9dSBarry Smith    Notes:
39576bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3958a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
39596bc08f3fSLois Curfman McInnes    order in which they were set.
3960639f9d9dSBarry Smith 
396195452b02SPatrick Sanan    Fortran Notes:
396295452b02SPatrick Sanan     Only a single monitor function can be set for each SNES object
3963025f1a04SBarry Smith 
396436851e7fSLois Curfman McInnes    Level: intermediate
396536851e7fSLois Curfman McInnes 
3966bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
39679b94acceSBarry Smith @*/
39686e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
39699b94acceSBarry Smith {
3970b90d0a6eSBarry Smith   PetscInt       i;
3971649052a6SBarry Smith   PetscErrorCode ierr;
397278064530SBarry Smith   PetscBool      identical;
3973b90d0a6eSBarry Smith 
39743a40ed3dSBarry Smith   PetscFunctionBegin;
39750700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3976b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
397778064530SBarry Smith     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
397878064530SBarry Smith     if (identical) PetscFunctionReturn(0);
3979649052a6SBarry Smith   }
398078064530SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
39816e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3982b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3983639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
39843a40ed3dSBarry Smith   PetscFunctionReturn(0);
39859b94acceSBarry Smith }
39869b94acceSBarry Smith 
3987a278d85bSSatish Balay /*@
3988a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
39895cd90555SBarry Smith 
39903f9fe445SBarry Smith    Logically Collective on SNES
3991c7afd0dbSLois Curfman McInnes 
39925cd90555SBarry Smith    Input Parameters:
39935cd90555SBarry Smith .  snes - the SNES context
39945cd90555SBarry Smith 
39951a480d89SAdministrator    Options Database Key:
3996a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3997a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3998c7afd0dbSLois Curfman McInnes     set via the options database
39995cd90555SBarry Smith 
40005cd90555SBarry Smith    Notes:
40015cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
40025cd90555SBarry Smith 
400336851e7fSLois Curfman McInnes    Level: intermediate
400436851e7fSLois Curfman McInnes 
4005a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
40065cd90555SBarry Smith @*/
40077087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
40085cd90555SBarry Smith {
4009d952e501SBarry Smith   PetscErrorCode ierr;
4010d952e501SBarry Smith   PetscInt       i;
4011d952e501SBarry Smith 
40125cd90555SBarry Smith   PetscFunctionBegin;
40130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4014d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
4015d952e501SBarry Smith     if (snes->monitordestroy[i]) {
40163c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
4017d952e501SBarry Smith     }
4018d952e501SBarry Smith   }
40195cd90555SBarry Smith   snes->numbermonitors = 0;
40205cd90555SBarry Smith   PetscFunctionReturn(0);
40215cd90555SBarry Smith }
40225cd90555SBarry Smith 
4023bf388a1fSBarry Smith /*MC
4024bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4025bf388a1fSBarry Smith 
4026bf388a1fSBarry Smith      Synopsis:
4027aaa7dc30SBarry Smith      #include <petscsnes.h>
4028bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
4029bf388a1fSBarry Smith 
40301843f636SBarry Smith      Collective on snes
40311843f636SBarry Smith 
40321843f636SBarry Smith     Input Parameters:
4033bf388a1fSBarry Smith +    snes - the SNES context
4034bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
4035bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
4036bf388a1fSBarry Smith .    gnorm - 2-norm of current step
40371843f636SBarry Smith .    f - 2-norm of function
40381843f636SBarry Smith -    cctx - [optional] convergence context
40391843f636SBarry Smith 
40401843f636SBarry Smith     Output Parameter:
40411843f636SBarry Smith .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4042bf388a1fSBarry Smith 
4043878cb397SSatish Balay    Level: intermediate
4044bf388a1fSBarry Smith 
4045bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
4046bf388a1fSBarry Smith M*/
4047bf388a1fSBarry Smith 
40489b94acceSBarry Smith /*@C
40499b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
40509b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
40519b94acceSBarry Smith 
40523f9fe445SBarry Smith    Logically Collective on SNES
4053fee21e36SBarry Smith 
4054c7afd0dbSLois Curfman McInnes    Input Parameters:
4055c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4056bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
40570298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
4058cf90aa19SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran)
40599b94acceSBarry Smith 
406036851e7fSLois Curfman McInnes    Level: advanced
406136851e7fSLois Curfman McInnes 
4062e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
40639b94acceSBarry Smith @*/
4064bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
40659b94acceSBarry Smith {
40667f7931b9SBarry Smith   PetscErrorCode ierr;
40677f7931b9SBarry Smith 
40683a40ed3dSBarry Smith   PetscFunctionBegin;
40690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4070e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
40717f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
40727f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
40737f7931b9SBarry Smith   }
4074bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
40757f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
407685385478SLisandro Dalcin   snes->cnvP                  = cctx;
40773a40ed3dSBarry Smith   PetscFunctionReturn(0);
40789b94acceSBarry Smith }
40799b94acceSBarry Smith 
408052baeb72SSatish Balay /*@
4081184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
4082184914b5SBarry Smith 
4083184914b5SBarry Smith    Not Collective
4084184914b5SBarry Smith 
4085184914b5SBarry Smith    Input Parameter:
4086184914b5SBarry Smith .  snes - the SNES context
4087184914b5SBarry Smith 
4088184914b5SBarry Smith    Output Parameter:
40894d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
4090184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
4091184914b5SBarry Smith 
40926a4d7782SBarry Smith    Options Database:
40936a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
40946a4d7782SBarry Smith 
4095184914b5SBarry Smith    Level: intermediate
4096184914b5SBarry Smith 
409795452b02SPatrick Sanan    Notes:
409895452b02SPatrick Sanan     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
4099184914b5SBarry Smith 
410033866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
4101184914b5SBarry Smith @*/
41027087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
4103184914b5SBarry Smith {
4104184914b5SBarry Smith   PetscFunctionBegin;
41050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41064482741eSBarry Smith   PetscValidPointer(reason,2);
4107184914b5SBarry Smith   *reason = snes->reason;
4108184914b5SBarry Smith   PetscFunctionReturn(0);
4109184914b5SBarry Smith }
4110184914b5SBarry Smith 
4111c4421ceaSFande Kong /*@C
4112c4421ceaSFande Kong    SNESGetConvergedReasonString - Return a human readable string for snes converged reason
4113c4421ceaSFande Kong 
4114c4421ceaSFande Kong    Not Collective
4115c4421ceaSFande Kong 
4116c4421ceaSFande Kong    Input Parameter:
4117c4421ceaSFande Kong .  snes - the SNES context
4118c4421ceaSFande Kong 
4119c4421ceaSFande Kong    Output Parameter:
4120c4421ceaSFande Kong .  strreason - a human readable string that describes SNES converged reason
4121c4421ceaSFande Kong 
4122*99c90e12SSatish Balay    Level: beginner
4123c4421ceaSFande Kong 
4124c4421ceaSFande Kong .seealso: SNESGetConvergedReason()
4125c4421ceaSFande Kong @*/
4126c4421ceaSFande Kong PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason)
4127c4421ceaSFande Kong {
4128c4421ceaSFande Kong   PetscFunctionBegin;
4129c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4130c4421ceaSFande Kong   PetscValidCharPointer(strreason,2);
4131c4421ceaSFande Kong   *strreason = SNESConvergedReasons[snes->reason];
4132c4421ceaSFande Kong   PetscFunctionReturn(0);
4133c4421ceaSFande Kong }
4134c4421ceaSFande Kong 
413533866048SMatthew G. Knepley /*@
413633866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
413733866048SMatthew G. Knepley 
413833866048SMatthew G. Knepley    Not Collective
413933866048SMatthew G. Knepley 
414033866048SMatthew G. Knepley    Input Parameters:
414133866048SMatthew G. Knepley +  snes - the SNES context
414233866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
414333866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
414433866048SMatthew G. Knepley 
414533866048SMatthew G. Knepley    Level: intermediate
414633866048SMatthew G. Knepley 
414733866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
414833866048SMatthew G. Knepley @*/
414933866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
415033866048SMatthew G. Knepley {
415133866048SMatthew G. Knepley   PetscFunctionBegin;
415233866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
415333866048SMatthew G. Knepley   snes->reason = reason;
415433866048SMatthew G. Knepley   PetscFunctionReturn(0);
415533866048SMatthew G. Knepley }
415633866048SMatthew G. Knepley 
4157c9005455SLois Curfman McInnes /*@
4158c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
4159c9005455SLois Curfman McInnes 
41603f9fe445SBarry Smith    Logically Collective on SNES
4161fee21e36SBarry Smith 
4162c7afd0dbSLois Curfman McInnes    Input Parameters:
4163c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
41648c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
4165cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
4166758f92a0SBarry Smith .  na  - size of a and its
416764731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
4168758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
4169c7afd0dbSLois Curfman McInnes 
4170308dcc3eSBarry Smith    Notes:
41710298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
4172308dcc3eSBarry Smith    default array of length 10000 is allocated.
4173308dcc3eSBarry Smith 
4174c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
4175c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
4176c9005455SLois Curfman McInnes    during the section of code that is being timed.
4177c9005455SLois Curfman McInnes 
417836851e7fSLois Curfman McInnes    Level: intermediate
417936851e7fSLois Curfman McInnes 
418008405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
4181758f92a0SBarry Smith 
4182c9005455SLois Curfman McInnes @*/
41837087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
4184c9005455SLois Curfman McInnes {
4185308dcc3eSBarry Smith   PetscErrorCode ierr;
4186308dcc3eSBarry Smith 
41873a40ed3dSBarry Smith   PetscFunctionBegin;
41880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41897a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
4190a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
41917a1ec6d4SBarry Smith   if (!a) {
4192308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
4193071fcb05SBarry Smith     ierr = PetscCalloc2(na,&a,na,&its);CHKERRQ(ierr);
4194071fcb05SBarry Smith     snes->conv_hist_alloc = PETSC_TRUE;
4195308dcc3eSBarry Smith   }
4196c9005455SLois Curfman McInnes   snes->conv_hist       = a;
4197758f92a0SBarry Smith   snes->conv_hist_its   = its;
4198758f92a0SBarry Smith   snes->conv_hist_max   = na;
4199a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
4200758f92a0SBarry Smith   snes->conv_hist_reset = reset;
4201758f92a0SBarry Smith   PetscFunctionReturn(0);
4202758f92a0SBarry Smith }
4203758f92a0SBarry Smith 
4204308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4205c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
4206c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
420799e0435eSBarry Smith 
42088cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4209308dcc3eSBarry Smith {
4210308dcc3eSBarry Smith   mxArray   *mat;
4211308dcc3eSBarry Smith   PetscInt  i;
4212308dcc3eSBarry Smith   PetscReal *ar;
4213308dcc3eSBarry Smith 
4214308dcc3eSBarry Smith   PetscFunctionBegin;
4215308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
4216308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
4217f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4218308dcc3eSBarry Smith   PetscFunctionReturn(mat);
4219308dcc3eSBarry Smith }
4220308dcc3eSBarry Smith #endif
4221308dcc3eSBarry Smith 
42220c4c9dddSBarry Smith /*@C
4223758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4224758f92a0SBarry Smith 
42253f9fe445SBarry Smith    Not Collective
4226758f92a0SBarry Smith 
4227758f92a0SBarry Smith    Input Parameter:
4228758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
4229758f92a0SBarry Smith 
4230758f92a0SBarry Smith    Output Parameters:
4231a2b725a8SWilliam Gropp +  a   - array to hold history
4232758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
4233758f92a0SBarry Smith          negative if not converged) for each solve.
4234758f92a0SBarry Smith -  na  - size of a and its
4235758f92a0SBarry Smith 
4236758f92a0SBarry Smith    Notes:
4237758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
4238758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4239758f92a0SBarry Smith 
4240758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
4241758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
4242758f92a0SBarry Smith    during the section of code that is being timed.
4243758f92a0SBarry Smith 
4244758f92a0SBarry Smith    Level: intermediate
4245758f92a0SBarry Smith 
42465ea7661aSPierre Jolivet .seealso: SNESSetConvergenceHistory()
4247758f92a0SBarry Smith 
4248758f92a0SBarry Smith @*/
42497087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
4250758f92a0SBarry Smith {
4251758f92a0SBarry Smith   PetscFunctionBegin;
42520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4253758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
4254758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
4255758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
42563a40ed3dSBarry Smith   PetscFunctionReturn(0);
4257c9005455SLois Curfman McInnes }
4258c9005455SLois Curfman McInnes 
4259ac226902SBarry Smith /*@C
426076b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
4261eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
42627e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
426376b2cf59SMatthew Knepley 
42643f9fe445SBarry Smith   Logically Collective on SNES
426576b2cf59SMatthew Knepley 
426676b2cf59SMatthew Knepley   Input Parameters:
4267a2b725a8SWilliam Gropp + snes - The nonlinear solver context
4268a2b725a8SWilliam Gropp - func - The function
426976b2cf59SMatthew Knepley 
427076b2cf59SMatthew Knepley   Calling sequence of func:
4271a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step);
427276b2cf59SMatthew Knepley 
427376b2cf59SMatthew Knepley . step - The current step of the iteration
427476b2cf59SMatthew Knepley 
4275fe97e370SBarry Smith   Level: advanced
4276fe97e370SBarry Smith 
4277fe97e370SBarry Smith   Note: 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()
4278fe97e370SBarry Smith         This is not used by most users.
427976b2cf59SMatthew Knepley 
42808d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
428176b2cf59SMatthew Knepley @*/
42827087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
428376b2cf59SMatthew Knepley {
428476b2cf59SMatthew Knepley   PetscFunctionBegin;
42850700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
4286e7788613SBarry Smith   snes->ops->update = func;
428776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
428876b2cf59SMatthew Knepley }
428976b2cf59SMatthew Knepley 
42909b94acceSBarry Smith /*
42919b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
42929b94acceSBarry Smith    positive parameter delta.
42939b94acceSBarry Smith 
42949b94acceSBarry Smith     Input Parameters:
4295c7afd0dbSLois Curfman McInnes +   snes - the SNES context
42969b94acceSBarry Smith .   y - approximate solution of linear system
42979b94acceSBarry Smith .   fnorm - 2-norm of current function
4298c7afd0dbSLois Curfman McInnes -   delta - trust region size
42999b94acceSBarry Smith 
43009b94acceSBarry Smith     Output Parameters:
4301c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
43029b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
43039b94acceSBarry Smith     region, and exceeds zero otherwise.
4304c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
43059b94acceSBarry Smith 
43069b94acceSBarry Smith     Note:
430704d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
43089b94acceSBarry Smith     is set to be the maximum allowable step size.
43099b94acceSBarry Smith 
43109b94acceSBarry Smith */
4311dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
43129b94acceSBarry Smith {
4313064f8208SBarry Smith   PetscReal      nrm;
4314ea709b57SSatish Balay   PetscScalar    cnorm;
4315dfbe8321SBarry Smith   PetscErrorCode ierr;
43163a40ed3dSBarry Smith 
43173a40ed3dSBarry Smith   PetscFunctionBegin;
43180700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43190700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4320c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
4321184914b5SBarry Smith 
4322064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
4323064f8208SBarry Smith   if (nrm > *delta) {
4324064f8208SBarry Smith     nrm     = *delta/nrm;
4325064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
4326064f8208SBarry Smith     cnorm   = nrm;
43272dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
43289b94acceSBarry Smith     *ynorm  = *delta;
43299b94acceSBarry Smith   } else {
43309b94acceSBarry Smith     *gpnorm = 0.0;
4331064f8208SBarry Smith     *ynorm  = nrm;
43329b94acceSBarry Smith   }
43333a40ed3dSBarry Smith   PetscFunctionReturn(0);
43349b94acceSBarry Smith }
43359b94acceSBarry Smith 
433691f3e32bSBarry Smith /*@C
433719a666eeSBarry Smith    SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer
43382a359c20SBarry Smith 
43392a359c20SBarry Smith    Collective on SNES
43402a359c20SBarry Smith 
43412a359c20SBarry Smith    Parameter:
43422a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
43432a359c20SBarry Smith -  viewer - the viewer to display the reason
43442a359c20SBarry Smith 
43452a359c20SBarry Smith 
43462a359c20SBarry Smith    Options Database Keys:
4347ee300463SSatish Balay +  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
4348ee300463SSatish Balay -  -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4349eafd5ff0SAlex Lindsay 
435019a666eeSBarry Smith   Notes:
435119a666eeSBarry Smith      To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default,
435219a666eeSBarry Smith      use PETSC_VIEWER_FAILED to only display a reason if it fails.
43532a359c20SBarry Smith 
43542a359c20SBarry Smith    Level: beginner
43552a359c20SBarry Smith 
435619a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(),
435719a666eeSBarry Smith           PetscViewerPushFormat(), PetscViewerPopFormat()
43582a359c20SBarry Smith 
43592a359c20SBarry Smith @*/
436019a666eeSBarry Smith PetscErrorCode  SNESConvergedReasonView(SNES snes,PetscViewer viewer)
43612a359c20SBarry Smith {
436275cca76cSMatthew G. Knepley   PetscViewerFormat format;
43632a359c20SBarry Smith   PetscBool         isAscii;
436475cca76cSMatthew G. Knepley   PetscErrorCode    ierr;
43652a359c20SBarry Smith 
43662a359c20SBarry Smith   PetscFunctionBegin;
436719a666eeSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
43682a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
43692a359c20SBarry Smith   if (isAscii) {
437075cca76cSMatthew G. Knepley     ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
43712a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
437275cca76cSMatthew G. Knepley     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
437375cca76cSMatthew G. Knepley       DM              dm;
437475cca76cSMatthew G. Knepley       Vec             u;
437575cca76cSMatthew G. Knepley       PetscDS         prob;
437675cca76cSMatthew G. Knepley       PetscInt        Nf, f;
437795cbbfd3SMatthew G. Knepley       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
437895cbbfd3SMatthew G. Knepley       void            **exactCtx;
437975cca76cSMatthew G. Knepley       PetscReal       error;
438075cca76cSMatthew G. Knepley 
438175cca76cSMatthew G. Knepley       ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
438275cca76cSMatthew G. Knepley       ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr);
438375cca76cSMatthew G. Knepley       ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
438475cca76cSMatthew G. Knepley       ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
438595cbbfd3SMatthew G. Knepley       ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr);
438695cbbfd3SMatthew G. Knepley       for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);}
438795cbbfd3SMatthew G. Knepley       ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr);
438895cbbfd3SMatthew G. Knepley       ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr);
438975cca76cSMatthew G. Knepley       if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);}
439075cca76cSMatthew G. Knepley       else                 {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);}
439175cca76cSMatthew G. Knepley     }
4392eafd5ff0SAlex Lindsay     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
43932a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
43942a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
43952a359c20SBarry Smith       } else {
43962a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
43972a359c20SBarry Smith       }
4398eafd5ff0SAlex Lindsay     } else if (snes->reason <= 0) {
43992a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
44002a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
44012a359c20SBarry Smith       } else {
44022a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
44032a359c20SBarry Smith       }
44042a359c20SBarry Smith     }
44052a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
44062a359c20SBarry Smith   }
44072a359c20SBarry Smith   PetscFunctionReturn(0);
44082a359c20SBarry Smith }
44092a359c20SBarry Smith 
4410c4421ceaSFande Kong /*@C
4411c4421ceaSFande Kong    SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the
4412c4421ceaSFande Kong     end of the nonlinear solver to display the conver reason of the nonlinear solver.
4413c4421ceaSFande Kong 
4414c4421ceaSFande Kong    Logically Collective on SNES
4415c4421ceaSFande Kong 
4416c4421ceaSFande Kong    Input Parameters:
4417c4421ceaSFande Kong +  snes - the SNES context
4418c4421ceaSFande Kong .  f - the snes converged reason view function
4419c4421ceaSFande Kong .  vctx - [optional] user-defined context for private data for the
4420c4421ceaSFande Kong           snes converged reason view routine (use NULL if no context is desired)
4421c4421ceaSFande Kong -  reasonviewdestroy - [optional] routine that frees reasonview context
4422c4421ceaSFande Kong           (may be NULL)
4423c4421ceaSFande Kong 
4424c4421ceaSFande Kong    Options Database Keys:
4425c4421ceaSFande Kong +    -snes_converged_reason        - sets a default SNESConvergedReasonView()
4426c4421ceaSFande Kong -    -snes_converged_reason_view_cancel - cancels all converged reason viewers that have
4427c4421ceaSFande Kong                             been hardwired into a code by
4428c4421ceaSFande Kong                             calls to SNESConvergedReasonViewSet(), but
4429c4421ceaSFande Kong                             does not cancel those set via
4430c4421ceaSFande Kong                             the options database.
4431c4421ceaSFande Kong 
4432c4421ceaSFande Kong    Notes:
4433c4421ceaSFande Kong    Several different converged reason view routines may be set by calling
4434c4421ceaSFande Kong    SNESConvergedReasonViewSet() multiple times; all will be called in the
4435c4421ceaSFande Kong    order in which they were set.
4436c4421ceaSFande Kong 
4437c4421ceaSFande Kong    Level: intermediate
4438c4421ceaSFande Kong 
4439c4421ceaSFande Kong .seealso: SNESConvergedReasonView(), SNESConvergedReasonViewCancel()
4440c4421ceaSFande Kong @*/
4441c4421ceaSFande Kong PetscErrorCode  SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**))
4442c4421ceaSFande Kong {
4443c4421ceaSFande Kong   PetscInt       i;
4444c4421ceaSFande Kong   PetscErrorCode ierr;
4445c4421ceaSFande Kong   PetscBool      identical;
4446c4421ceaSFande Kong 
4447c4421ceaSFande Kong   PetscFunctionBegin;
4448c4421ceaSFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4449c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews;i++) {
4450c4421ceaSFande Kong     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical);CHKERRQ(ierr);
4451c4421ceaSFande Kong     if (identical) PetscFunctionReturn(0);
4452c4421ceaSFande Kong   }
4453c4421ceaSFande Kong   if (snes->numberreasonviews >= MAXSNESREASONVIEWS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set");
4454c4421ceaSFande Kong   snes->reasonview[snes->numberreasonviews]          = f;
4455c4421ceaSFande Kong   snes->reasonviewdestroy[snes->numberreasonviews]   = reasonviewdestroy;
4456c4421ceaSFande Kong   snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx;
4457c4421ceaSFande Kong   PetscFunctionReturn(0);
4458c4421ceaSFande Kong }
4459c4421ceaSFande Kong 
446091f3e32bSBarry Smith /*@
446119a666eeSBarry Smith   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
4462c4421ceaSFande Kong                                        All the user-provided convergedReasonView routines will be involved as well, if they exist.
44632a359c20SBarry Smith 
44642a359c20SBarry Smith   Collective on SNES
44652a359c20SBarry Smith 
44662a359c20SBarry Smith   Input Parameters:
44672a359c20SBarry Smith . snes   - the SNES object
44682a359c20SBarry Smith 
44692a359c20SBarry Smith   Level: intermediate
44702a359c20SBarry Smith 
447119a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView()
447219a666eeSBarry Smith 
44732a359c20SBarry Smith @*/
447419a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
44752a359c20SBarry Smith {
44762a359c20SBarry Smith   PetscErrorCode    ierr;
44772a359c20SBarry Smith   PetscViewer       viewer;
44782a359c20SBarry Smith   PetscBool         flg;
44792a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
44802a359c20SBarry Smith   PetscViewerFormat format;
4481c4421ceaSFande Kong   PetscInt          i;
44822a359c20SBarry Smith 
44832a359c20SBarry Smith   PetscFunctionBegin;
44842a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
44852a359c20SBarry Smith   incall = PETSC_TRUE;
4486c4421ceaSFande Kong 
4487c4421ceaSFande Kong   /* All user-provided viewers are called first, if they exist. */
4488c4421ceaSFande Kong   for (i=0; i<snes->numberreasonviews; i++) {
4489c4421ceaSFande Kong     ierr = (*snes->reasonview[i])(snes,snes->reasonviewcontext[i]);CHKERRQ(ierr);
4490c4421ceaSFande Kong   }
4491c4421ceaSFande Kong 
4492c4421ceaSFande Kong   /* Call PETSc default routine if users ask for it */
449316413a6aSBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
44942a359c20SBarry Smith   if (flg) {
44952a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
449619a666eeSBarry Smith     ierr = SNESConvergedReasonView(snes,viewer);CHKERRQ(ierr);
44972a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
44982a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
44992a359c20SBarry Smith   }
45002a359c20SBarry Smith   incall = PETSC_FALSE;
45012a359c20SBarry Smith   PetscFunctionReturn(0);
45022a359c20SBarry Smith }
45032a359c20SBarry Smith 
4504487a658cSBarry Smith /*@
4505f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
4506f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
45079b94acceSBarry Smith 
4508c7afd0dbSLois Curfman McInnes    Collective on SNES
4509c7afd0dbSLois Curfman McInnes 
4510b2002411SLois Curfman McInnes    Input Parameters:
4511c7afd0dbSLois Curfman McInnes +  snes - the SNES context
45120298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
451385385478SLisandro Dalcin -  x - the solution vector.
45149b94acceSBarry Smith 
4515b2002411SLois Curfman McInnes    Notes:
45168ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
45178ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
45188ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
45198ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
45208ddd3da0SLois Curfman McInnes 
452136851e7fSLois Curfman McInnes    Level: beginner
452236851e7fSLois Curfman McInnes 
4523c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
45249b94acceSBarry Smith @*/
45257087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
45269b94acceSBarry Smith {
4527dfbe8321SBarry Smith   PetscErrorCode    ierr;
4528ace3abfcSBarry Smith   PetscBool         flg;
4529efd51863SBarry Smith   PetscInt          grid;
45300298fd71SBarry Smith   Vec               xcreated = NULL;
4531caa4e7f2SJed Brown   DM                dm;
4532052efed2SBarry Smith 
45333a40ed3dSBarry Smith   PetscFunctionBegin;
45340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4535a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4536a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
45370700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
453885385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
453985385478SLisandro Dalcin 
454034b4d3a8SMatthew G. Knepley   /* High level operations using the nonlinear solver */
454106fc46c8SMatthew G. Knepley   {
454206fc46c8SMatthew G. Knepley     PetscViewer       viewer;
454306fc46c8SMatthew G. Knepley     PetscViewerFormat format;
45447c88af5aSMatthew G. Knepley     PetscInt          num;
454506fc46c8SMatthew G. Knepley     PetscBool         flg;
454606fc46c8SMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
454706fc46c8SMatthew G. Knepley 
454806fc46c8SMatthew G. Knepley     if (!incall) {
454934b4d3a8SMatthew G. Knepley       /* Estimate the convergence rate of the discretization */
455016413a6aSBarry Smith       ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr);
455106fc46c8SMatthew G. Knepley       if (flg) {
455206fc46c8SMatthew G. Knepley         PetscConvEst conv;
455346079b62SMatthew G. Knepley         DM           dm;
455446079b62SMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
455546079b62SMatthew G. Knepley         PetscInt     Nf;
455606fc46c8SMatthew G. Knepley 
455706fc46c8SMatthew G. Knepley         incall = PETSC_TRUE;
455846079b62SMatthew G. Knepley         ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
455946079b62SMatthew G. Knepley         ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4560ca5a3622SMatthew G. Knepley         ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr);
456106fc46c8SMatthew G. Knepley         ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr);
4562900f6b5bSMatthew G. Knepley         ierr = PetscConvEstSetSolver(conv, (PetscObject) snes);CHKERRQ(ierr);
456306fc46c8SMatthew G. Knepley         ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr);
45640955ed61SMatthew G. Knepley         ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr);
456546079b62SMatthew G. Knepley         ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr);
456606fc46c8SMatthew G. Knepley         ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
456706fc46c8SMatthew G. Knepley         ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr);
456806fc46c8SMatthew G. Knepley         ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
456906fc46c8SMatthew G. Knepley         ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
457006fc46c8SMatthew G. Knepley         ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr);
457146079b62SMatthew G. Knepley         ierr = PetscFree(alpha);CHKERRQ(ierr);
457206fc46c8SMatthew G. Knepley         incall = PETSC_FALSE;
457306fc46c8SMatthew G. Knepley       }
457434b4d3a8SMatthew G. Knepley       /* Adaptively refine the initial grid */
4575b2588ea6SMatthew G. Knepley       num  = 1;
4576b2588ea6SMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr);
457734b4d3a8SMatthew G. Knepley       if (flg) {
457834b4d3a8SMatthew G. Knepley         DMAdaptor adaptor;
457934b4d3a8SMatthew G. Knepley 
458034b4d3a8SMatthew G. Knepley         incall = PETSC_TRUE;
4581ea13f565SStefano Zampini         ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr);
458234b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
4583b2588ea6SMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
458434b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
458534b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
458634b4d3a8SMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr);
458734b4d3a8SMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
458834b4d3a8SMatthew G. Knepley         incall = PETSC_FALSE;
458934b4d3a8SMatthew G. Knepley       }
45907c88af5aSMatthew G. Knepley       /* Use grid sequencing to adapt */
45917c88af5aSMatthew G. Knepley       num  = 0;
45927c88af5aSMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr);
45937c88af5aSMatthew G. Knepley       if (num) {
45947c88af5aSMatthew G. Knepley         DMAdaptor adaptor;
45957c88af5aSMatthew G. Knepley 
45967c88af5aSMatthew G. Knepley         incall = PETSC_TRUE;
4597ea13f565SStefano Zampini         ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr);
45987c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
45997c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
46007c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
46017c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
46027c88af5aSMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr);
46037c88af5aSMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
46047c88af5aSMatthew G. Knepley         incall = PETSC_FALSE;
46057c88af5aSMatthew G. Knepley       }
460606fc46c8SMatthew G. Knepley     }
460706fc46c8SMatthew G. Knepley   }
4608caa4e7f2SJed Brown   if (!x) {
4609caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4610caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
4611a69afd8bSBarry Smith     x    = xcreated;
4612a69afd8bSBarry Smith   }
4613ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
4614f05ece33SBarry Smith 
4615ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
4616efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
4617efd51863SBarry Smith 
461885385478SLisandro Dalcin     /* set solution vector */
4619efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
46206bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
462185385478SLisandro Dalcin     snes->vec_sol = x;
4622caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4623caa4e7f2SJed Brown 
4624caa4e7f2SJed Brown     /* set affine vector if provided */
462585385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
46266bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
462785385478SLisandro Dalcin     snes->vec_rhs = b;
462885385478SLisandro Dalcin 
4629bfdd6862SPatrick Farrell     if (snes->vec_rhs && (snes->vec_func == snes->vec_rhs)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Right hand side vector cannot be function vector");
4630154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4631154060b5SMatthew G. Knepley     if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
4632154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4633154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
4634154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
4635154060b5SMatthew G. Knepley     }
4636154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
463770e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
46383f149594SLisandro Dalcin 
46397eee914bSBarry Smith     if (!grid) {
46407eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
4641d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
4642d25893d9SBarry Smith       }
4643dd568438SSatish Balay     }
4644d25893d9SBarry Smith 
4645abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4646971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4647d5e45103SBarry Smith 
46483f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
46494936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
465085385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
465117186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4652422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
46533f149594SLisandro Dalcin 
465437ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
465537ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
465637ec4e1aSPeter Brune 
465716413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
4658da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
4659c4421ceaSFande Kong     /* Call converged reason views. This may involve user-provided viewers as well */
466019a666eeSBarry Smith     ierr = SNESConvergedReasonViewFromOptions(snes);CHKERRQ(ierr);
46615968eb51SBarry Smith 
4662ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
46639c8e83a9SBarry Smith     if (snes->reason < 0) break;
4664efd51863SBarry Smith     if (grid <  snes->gridsequence) {
4665efd51863SBarry Smith       DM  fine;
4666efd51863SBarry Smith       Vec xnew;
4667efd51863SBarry Smith       Mat interp;
4668efd51863SBarry Smith 
4669ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
4670ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
46710298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4672efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4673efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4674c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4675efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4676efd51863SBarry Smith       x    = xnew;
4677efd51863SBarry Smith 
4678efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
4679efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4680352f405dSMatthew G. Knepley       ierr = SNESResetFromOptions(snes);CHKERRQ(ierr);
4681efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4682ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4683efd51863SBarry Smith     }
4684efd51863SBarry Smith   }
4685ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4686685405a1SBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
4687c0f0dcc3SMatthew G. Knepley   ierr = DMMonitor(snes->dm);CHKERRQ(ierr);
46883f7e2da0SPeter Brune 
4689a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4690e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
46913a40ed3dSBarry Smith   PetscFunctionReturn(0);
46929b94acceSBarry Smith }
46939b94acceSBarry Smith 
46949b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
46959b94acceSBarry Smith 
469682bf6240SBarry Smith /*@C
46974b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
46989b94acceSBarry Smith 
4699fee21e36SBarry Smith    Collective on SNES
4700fee21e36SBarry Smith 
4701c7afd0dbSLois Curfman McInnes    Input Parameters:
4702c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4703454a90a3SBarry Smith -  type - a known method
4704c7afd0dbSLois Curfman McInnes 
4705c7afd0dbSLois Curfman McInnes    Options Database Key:
4706454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
470704d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4708ae12b187SLois Curfman McInnes 
47099b94acceSBarry Smith    Notes:
4710e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
471104d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4712c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
4713a2b725a8SWilliam Gropp -    SNESNEWTONTR - Newton's method with trust region
4714c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
47159b94acceSBarry Smith 
4716ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4717ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4718ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4719ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4720ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4721ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4722ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4723ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4724ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4725b0a32e0cSBarry Smith   appropriate method.
472636851e7fSLois Curfman McInnes 
472795452b02SPatrick Sanan     Developer Notes:
472895452b02SPatrick Sanan     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
47298f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
47308f6c3df8SBarry Smith 
473136851e7fSLois Curfman McInnes   Level: intermediate
4732a703fe33SLois Curfman McInnes 
47338f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4734435da068SBarry Smith 
47359b94acceSBarry Smith @*/
473619fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
47379b94acceSBarry Smith {
4738dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
4739ace3abfcSBarry Smith   PetscBool      match;
47403a40ed3dSBarry Smith 
47413a40ed3dSBarry Smith   PetscFunctionBegin;
47420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47434482741eSBarry Smith   PetscValidCharPointer(type,2);
474482bf6240SBarry Smith 
4745251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
47460f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
474792ff6ae8SBarry Smith 
47481c9cd337SJed Brown   ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4749e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
475075396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4751b5c23020SJed Brown   if (snes->ops->destroy) {
4752b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
47530298fd71SBarry Smith     snes->ops->destroy = NULL;
4754b5c23020SJed Brown   }
475575396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
47569e5d0892SLisandro Dalcin   snes->ops->setup          = NULL;
47579e5d0892SLisandro Dalcin   snes->ops->solve          = NULL;
47589e5d0892SLisandro Dalcin   snes->ops->view           = NULL;
47599e5d0892SLisandro Dalcin   snes->ops->setfromoptions = NULL;
47609e5d0892SLisandro Dalcin   snes->ops->destroy        = NULL;
47617fe760d5SStefano Zampini 
47627fe760d5SStefano Zampini   /* It may happen the user has customized the line search before calling SNESSetType */
47637fe760d5SStefano Zampini   if (((PetscObject)snes)->type_name) {
4764d8d34be6SBarry Smith     ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
47657fe760d5SStefano Zampini   }
47667fe760d5SStefano Zampini 
476775396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
476875396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4769f5af7f23SKarl Rupp 
4770454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
477103bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
47723a40ed3dSBarry Smith   PetscFunctionReturn(0);
47739b94acceSBarry Smith }
47749b94acceSBarry Smith 
47759b94acceSBarry Smith /*@C
47769a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
47779b94acceSBarry Smith 
4778c7afd0dbSLois Curfman McInnes    Not Collective
4779c7afd0dbSLois Curfman McInnes 
47809b94acceSBarry Smith    Input Parameter:
47814b0e389bSBarry Smith .  snes - nonlinear solver context
47829b94acceSBarry Smith 
47839b94acceSBarry Smith    Output Parameter:
47843a7fca6bSBarry Smith .  type - SNES method (a character string)
47859b94acceSBarry Smith 
478636851e7fSLois Curfman McInnes    Level: intermediate
478736851e7fSLois Curfman McInnes 
47889b94acceSBarry Smith @*/
478919fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
47909b94acceSBarry Smith {
47913a40ed3dSBarry Smith   PetscFunctionBegin;
47920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47934482741eSBarry Smith   PetscValidPointer(type,2);
47947adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
47953a40ed3dSBarry Smith   PetscFunctionReturn(0);
47969b94acceSBarry Smith }
47979b94acceSBarry Smith 
47983cd8a7caSMatthew G. Knepley /*@
47993cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
48003cd8a7caSMatthew G. Knepley 
4801d083f849SBarry Smith   Logically Collective on SNES
48023cd8a7caSMatthew G. Knepley 
48033cd8a7caSMatthew G. Knepley   Input Parameters:
48043cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
48053cd8a7caSMatthew G. Knepley - u    - the solution vector
48063cd8a7caSMatthew G. Knepley 
48073cd8a7caSMatthew G. Knepley   Level: beginner
48083cd8a7caSMatthew G. Knepley 
48093cd8a7caSMatthew G. Knepley @*/
48103cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
48113cd8a7caSMatthew G. Knepley {
48123cd8a7caSMatthew G. Knepley   DM             dm;
48133cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
48143cd8a7caSMatthew G. Knepley 
48153cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
48163cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
48173cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
48183cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
48193cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
48203cd8a7caSMatthew G. Knepley 
48213cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
48223cd8a7caSMatthew G. Knepley 
48233cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
48243cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
48253cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
48263cd8a7caSMatthew G. Knepley }
48273cd8a7caSMatthew G. Knepley 
482852baeb72SSatish Balay /*@
48299b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4830c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
48319b94acceSBarry Smith 
4832c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4833c7afd0dbSLois Curfman McInnes 
48349b94acceSBarry Smith    Input Parameter:
48359b94acceSBarry Smith .  snes - the SNES context
48369b94acceSBarry Smith 
48379b94acceSBarry Smith    Output Parameter:
48389b94acceSBarry Smith .  x - the solution
48399b94acceSBarry Smith 
484070e92668SMatthew Knepley    Level: intermediate
484136851e7fSLois Curfman McInnes 
484285385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
48439b94acceSBarry Smith @*/
48447087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
48459b94acceSBarry Smith {
48463a40ed3dSBarry Smith   PetscFunctionBegin;
48470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48484482741eSBarry Smith   PetscValidPointer(x,2);
484985385478SLisandro Dalcin   *x = snes->vec_sol;
485070e92668SMatthew Knepley   PetscFunctionReturn(0);
485170e92668SMatthew Knepley }
485270e92668SMatthew Knepley 
485352baeb72SSatish Balay /*@
48549b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
48559b94acceSBarry Smith    stored.
48569b94acceSBarry Smith 
4857c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4858c7afd0dbSLois Curfman McInnes 
48599b94acceSBarry Smith    Input Parameter:
48609b94acceSBarry Smith .  snes - the SNES context
48619b94acceSBarry Smith 
48629b94acceSBarry Smith    Output Parameter:
48639b94acceSBarry Smith .  x - the solution update
48649b94acceSBarry Smith 
486536851e7fSLois Curfman McInnes    Level: advanced
486636851e7fSLois Curfman McInnes 
486785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
48689b94acceSBarry Smith @*/
48697087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
48709b94acceSBarry Smith {
48713a40ed3dSBarry Smith   PetscFunctionBegin;
48720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48734482741eSBarry Smith   PetscValidPointer(x,2);
487485385478SLisandro Dalcin   *x = snes->vec_sol_update;
48753a40ed3dSBarry Smith   PetscFunctionReturn(0);
48769b94acceSBarry Smith }
48779b94acceSBarry Smith 
48789b94acceSBarry Smith /*@C
48793638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
48809b94acceSBarry Smith 
4881a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4882c7afd0dbSLois Curfman McInnes 
48839b94acceSBarry Smith    Input Parameter:
48849b94acceSBarry Smith .  snes - the SNES context
48859b94acceSBarry Smith 
48869b94acceSBarry Smith    Output Parameter:
48870298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4888f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
48890298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
48909b94acceSBarry Smith 
489136851e7fSLois Curfman McInnes    Level: advanced
489236851e7fSLois Curfman McInnes 
489304edfde5SBarry Smith     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function
489404edfde5SBarry Smith 
4895bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
48969b94acceSBarry Smith @*/
4897f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
48989b94acceSBarry Smith {
4899a63bb30eSJed Brown   PetscErrorCode ierr;
49006cab3a1bSJed Brown   DM             dm;
4901a63bb30eSJed Brown 
49023a40ed3dSBarry Smith   PetscFunctionBegin;
49030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4904a63bb30eSJed Brown   if (r) {
4905a63bb30eSJed Brown     if (!snes->vec_func) {
4906a63bb30eSJed Brown       if (snes->vec_rhs) {
4907a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4908a63bb30eSJed Brown       } else if (snes->vec_sol) {
4909a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4910a63bb30eSJed Brown       } else if (snes->dm) {
4911a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4912a63bb30eSJed Brown       }
4913a63bb30eSJed Brown     }
4914a63bb30eSJed Brown     *r = snes->vec_func;
4915a63bb30eSJed Brown   }
49166cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4917f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
49183a40ed3dSBarry Smith   PetscFunctionReturn(0);
49199b94acceSBarry Smith }
49209b94acceSBarry Smith 
4921c79ef259SPeter Brune /*@C
4922be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4923c79ef259SPeter Brune 
4924c79ef259SPeter Brune    Input Parameter:
4925c79ef259SPeter Brune .  snes - the SNES context
4926c79ef259SPeter Brune 
4927c79ef259SPeter Brune    Output Parameter:
4928be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
49290298fd71SBarry Smith -  ctx    - the function context (or NULL)
4930c79ef259SPeter Brune 
4931c79ef259SPeter Brune    Level: advanced
4932c79ef259SPeter Brune 
4933be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4934c79ef259SPeter Brune @*/
4935c79ef259SPeter Brune 
4936be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4937646217ecSPeter Brune {
49386cab3a1bSJed Brown   PetscErrorCode ierr;
49396cab3a1bSJed Brown   DM             dm;
49406cab3a1bSJed Brown 
4941646217ecSPeter Brune   PetscFunctionBegin;
4942646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
49436cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4944be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4945646217ecSPeter Brune   PetscFunctionReturn(0);
4946646217ecSPeter Brune }
4947646217ecSPeter Brune 
49483c7409f5SSatish Balay /*@C
49493c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4950d850072dSLois Curfman McInnes    SNES options in the database.
49513c7409f5SSatish Balay 
49523f9fe445SBarry Smith    Logically Collective on SNES
4953fee21e36SBarry Smith 
4954c7afd0dbSLois Curfman McInnes    Input Parameter:
4955c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4956c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4957c7afd0dbSLois Curfman McInnes 
4958d850072dSLois Curfman McInnes    Notes:
4959a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4960c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4961d850072dSLois Curfman McInnes 
496236851e7fSLois Curfman McInnes    Level: advanced
496336851e7fSLois Curfman McInnes 
4964a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
49653c7409f5SSatish Balay @*/
49667087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
49673c7409f5SSatish Balay {
4968dfbe8321SBarry Smith   PetscErrorCode ierr;
49693c7409f5SSatish Balay 
49703a40ed3dSBarry Smith   PetscFunctionBegin;
49710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4972639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
49731cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
497435f5d045SPeter Brune   if (snes->linesearch) {
49757601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
497608b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
497735f5d045SPeter Brune   }
497835f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
49793a40ed3dSBarry Smith   PetscFunctionReturn(0);
49803c7409f5SSatish Balay }
49813c7409f5SSatish Balay 
49823c7409f5SSatish Balay /*@C
4983f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4984d850072dSLois Curfman McInnes    SNES options in the database.
49853c7409f5SSatish Balay 
49863f9fe445SBarry Smith    Logically Collective on SNES
4987fee21e36SBarry Smith 
4988c7afd0dbSLois Curfman McInnes    Input Parameters:
4989c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4990c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4991c7afd0dbSLois Curfman McInnes 
4992d850072dSLois Curfman McInnes    Notes:
4993a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4994c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4995d850072dSLois Curfman McInnes 
499636851e7fSLois Curfman McInnes    Level: advanced
499736851e7fSLois Curfman McInnes 
4998a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
49993c7409f5SSatish Balay @*/
50007087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
50013c7409f5SSatish Balay {
5002dfbe8321SBarry Smith   PetscErrorCode ierr;
50033c7409f5SSatish Balay 
50043a40ed3dSBarry Smith   PetscFunctionBegin;
50050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5006639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
50071cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
500835f5d045SPeter Brune   if (snes->linesearch) {
50097601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
501008b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
501135f5d045SPeter Brune   }
501235f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
50133a40ed3dSBarry Smith   PetscFunctionReturn(0);
50143c7409f5SSatish Balay }
50153c7409f5SSatish Balay 
50169ab63eb5SSatish Balay /*@C
50173c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
50183c7409f5SSatish Balay    SNES options in the database.
50193c7409f5SSatish Balay 
5020c7afd0dbSLois Curfman McInnes    Not Collective
5021c7afd0dbSLois Curfman McInnes 
50223c7409f5SSatish Balay    Input Parameter:
50233c7409f5SSatish Balay .  snes - the SNES context
50243c7409f5SSatish Balay 
50253c7409f5SSatish Balay    Output Parameter:
50263c7409f5SSatish Balay .  prefix - pointer to the prefix string used
50273c7409f5SSatish Balay 
502895452b02SPatrick Sanan    Notes:
502995452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
50309ab63eb5SSatish Balay    sufficient length to hold the prefix.
50319ab63eb5SSatish Balay 
503236851e7fSLois Curfman McInnes    Level: advanced
503336851e7fSLois Curfman McInnes 
5034a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
50353c7409f5SSatish Balay @*/
50367087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
50373c7409f5SSatish Balay {
5038dfbe8321SBarry Smith   PetscErrorCode ierr;
50393c7409f5SSatish Balay 
50403a40ed3dSBarry Smith   PetscFunctionBegin;
50410700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5042639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
50433a40ed3dSBarry Smith   PetscFunctionReturn(0);
50443c7409f5SSatish Balay }
50453c7409f5SSatish Balay 
5046b2002411SLois Curfman McInnes 
50473cea93caSBarry Smith /*@C
50481c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
50491c84c290SBarry Smith 
50501c84c290SBarry Smith    Not collective
50511c84c290SBarry Smith 
50521c84c290SBarry Smith    Input Parameters:
50531c84c290SBarry Smith +  name_solver - name of a new user-defined solver
50541c84c290SBarry Smith -  routine_create - routine to create method context
50551c84c290SBarry Smith 
50561c84c290SBarry Smith    Notes:
50571c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
50581c84c290SBarry Smith 
50591c84c290SBarry Smith    Sample usage:
50601c84c290SBarry Smith .vb
5061bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
50621c84c290SBarry Smith .ve
50631c84c290SBarry Smith 
50641c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
50651c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
50661c84c290SBarry Smith    or at runtime via the option
50671c84c290SBarry Smith $     -snes_type my_solver
50681c84c290SBarry Smith 
50691c84c290SBarry Smith    Level: advanced
50701c84c290SBarry Smith 
50711c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
50721c84c290SBarry Smith 
50731c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
50743cea93caSBarry Smith 
50757f6c08e0SMatthew Knepley   Level: advanced
50763cea93caSBarry Smith @*/
5077bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
5078b2002411SLois Curfman McInnes {
5079dfbe8321SBarry Smith   PetscErrorCode ierr;
5080b2002411SLois Curfman McInnes 
5081b2002411SLois Curfman McInnes   PetscFunctionBegin;
50821d36bdfdSBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
5083a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
5084b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
5085b2002411SLois Curfman McInnes }
5086da9b6338SBarry Smith 
50877087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
5088da9b6338SBarry Smith {
5089dfbe8321SBarry Smith   PetscErrorCode ierr;
509077431f27SBarry Smith   PetscInt       N,i,j;
5091da9b6338SBarry Smith   Vec            u,uh,fh;
5092da9b6338SBarry Smith   PetscScalar    value;
5093da9b6338SBarry Smith   PetscReal      norm;
5094da9b6338SBarry Smith 
5095da9b6338SBarry Smith   PetscFunctionBegin;
5096da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
5097da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
5098da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
5099da9b6338SBarry Smith 
5100da9b6338SBarry Smith   /* currently only works for sequential */
5101ea13f565SStefano Zampini   ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n");CHKERRQ(ierr);
5102da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
5103da9b6338SBarry Smith   for (i=0; i<N; i++) {
5104da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
5105ea13f565SStefano Zampini     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i);CHKERRQ(ierr);
5106da9b6338SBarry Smith     for (j=-10; j<11; j++) {
51078b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
5108da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
51093ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
5110da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
5111ea13f565SStefano Zampini       ierr  = PetscPrintf(PetscObjectComm((PetscObject)snes),"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
5112da9b6338SBarry Smith       value = -value;
5113da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
5114da9b6338SBarry Smith     }
5115da9b6338SBarry Smith   }
51166bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
51176bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
5118da9b6338SBarry Smith   PetscFunctionReturn(0);
5119da9b6338SBarry Smith }
512071f87433Sdalcinl 
512171f87433Sdalcinl /*@
5122fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
512371f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
512471f87433Sdalcinl    Newton method.
512571f87433Sdalcinl 
51263f9fe445SBarry Smith    Logically Collective on SNES
512771f87433Sdalcinl 
512871f87433Sdalcinl    Input Parameters:
512971f87433Sdalcinl +  snes - SNES context
513071f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
513171f87433Sdalcinl 
513264ba62caSBarry Smith     Options Database:
513364ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
513464ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
513564ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
513664ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
513764ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
513864ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
513964ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
514064ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
514164ba62caSBarry Smith 
514271f87433Sdalcinl    Notes:
514371f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
514471f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
514571f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
514671f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
514771f87433Sdalcinl    solver.
514871f87433Sdalcinl 
514971f87433Sdalcinl    Level: advanced
515071f87433Sdalcinl 
515171f87433Sdalcinl    Reference:
515271f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
515371f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
515471f87433Sdalcinl 
5155fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
515671f87433Sdalcinl @*/
51577087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
515871f87433Sdalcinl {
515971f87433Sdalcinl   PetscFunctionBegin;
51600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5161acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
516271f87433Sdalcinl   snes->ksp_ewconv = flag;
516371f87433Sdalcinl   PetscFunctionReturn(0);
516471f87433Sdalcinl }
516571f87433Sdalcinl 
516671f87433Sdalcinl /*@
5167fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
516871f87433Sdalcinl    for computing relative tolerance for linear solvers within an
516971f87433Sdalcinl    inexact Newton method.
517071f87433Sdalcinl 
517171f87433Sdalcinl    Not Collective
517271f87433Sdalcinl 
517371f87433Sdalcinl    Input Parameter:
517471f87433Sdalcinl .  snes - SNES context
517571f87433Sdalcinl 
517671f87433Sdalcinl    Output Parameter:
517771f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
517871f87433Sdalcinl 
517971f87433Sdalcinl    Notes:
518071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
518171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
518271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
518371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
518471f87433Sdalcinl    solver.
518571f87433Sdalcinl 
518671f87433Sdalcinl    Level: advanced
518771f87433Sdalcinl 
518871f87433Sdalcinl    Reference:
518971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
519071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
519171f87433Sdalcinl 
5192fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
519371f87433Sdalcinl @*/
51947087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
519571f87433Sdalcinl {
519671f87433Sdalcinl   PetscFunctionBegin;
51970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5198534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag,2);
519971f87433Sdalcinl   *flag = snes->ksp_ewconv;
520071f87433Sdalcinl   PetscFunctionReturn(0);
520171f87433Sdalcinl }
520271f87433Sdalcinl 
520371f87433Sdalcinl /*@
5204fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
520571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
520671f87433Sdalcinl    Newton method.
520771f87433Sdalcinl 
52083f9fe445SBarry Smith    Logically Collective on SNES
520971f87433Sdalcinl 
521071f87433Sdalcinl    Input Parameters:
521171f87433Sdalcinl +    snes - SNES context
521271f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
521371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
521471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
521571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
521671f87433Sdalcinl              (0 <= gamma2 <= 1)
521771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
521871f87433Sdalcinl .    alpha2 - power for safeguard
521971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
522071f87433Sdalcinl 
522171f87433Sdalcinl    Note:
522271f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
522371f87433Sdalcinl 
522471f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
522571f87433Sdalcinl 
522671f87433Sdalcinl    Level: advanced
522771f87433Sdalcinl 
522871f87433Sdalcinl    Reference:
522971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
523071f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
523171f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
523271f87433Sdalcinl 
5233fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
523471f87433Sdalcinl @*/
5235f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
523671f87433Sdalcinl {
5237fa9f3622SBarry Smith   SNESKSPEW *kctx;
52385fd66863SKarl Rupp 
523971f87433Sdalcinl   PetscFunctionBegin;
52400700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5241fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5242e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5243c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
5244c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
5245c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
5246c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
5247c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
5248c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
5249c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
525071f87433Sdalcinl 
525171f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
525271f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
525371f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
525471f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
525571f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
525671f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
525771f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
525871f87433Sdalcinl 
5259f23aa3ddSBarry Smith   if (kctx->version < 1 || kctx->version > 3) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
526057622a8eSBarry Smith   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0);
526157622a8eSBarry Smith   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0\n",(double)kctx->rtol_max);
526257622a8eSBarry Smith   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0\n",(double)kctx->gamma);
526357622a8eSBarry Smith   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0\n",(double)kctx->alpha);
526457622a8eSBarry Smith   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0\n",(double)kctx->threshold);
526571f87433Sdalcinl   PetscFunctionReturn(0);
526671f87433Sdalcinl }
526771f87433Sdalcinl 
526871f87433Sdalcinl /*@
5269fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
527071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
527171f87433Sdalcinl    Newton method.
527271f87433Sdalcinl 
527371f87433Sdalcinl    Not Collective
527471f87433Sdalcinl 
527571f87433Sdalcinl    Input Parameters:
527671f87433Sdalcinl      snes - SNES context
527771f87433Sdalcinl 
527871f87433Sdalcinl    Output Parameters:
527971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
528071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
528171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5282bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
528371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
528471f87433Sdalcinl .    alpha2 - power for safeguard
528571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
528671f87433Sdalcinl 
528771f87433Sdalcinl    Level: advanced
528871f87433Sdalcinl 
5289fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
529071f87433Sdalcinl @*/
5291bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
529271f87433Sdalcinl {
5293fa9f3622SBarry Smith   SNESKSPEW *kctx;
52945fd66863SKarl Rupp 
529571f87433Sdalcinl   PetscFunctionBegin;
52960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5297fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5298e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
529971f87433Sdalcinl   if (version)   *version   = kctx->version;
530071f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
530171f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
530271f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
530371f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
530471f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
530571f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
530671f87433Sdalcinl   PetscFunctionReturn(0);
530771f87433Sdalcinl }
530871f87433Sdalcinl 
5309d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
531071f87433Sdalcinl {
531171f87433Sdalcinl   PetscErrorCode ierr;
5312fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
531371f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
531471f87433Sdalcinl 
531571f87433Sdalcinl   PetscFunctionBegin;
5316d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
531730058271SDmitry Karpeev   if (!snes->iter) {
531830058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
531930058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
532030058271SDmitry Karpeev   }
5321f5af7f23SKarl Rupp   else {
532271f87433Sdalcinl     if (kctx->version == 1) {
532371f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
532471f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
532585ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
532671f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
532771f87433Sdalcinl     } else if (kctx->version == 2) {
532885ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
532985ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
533071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
533171f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
533285ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
533371f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
533485ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
533571f87433Sdalcinl       stol = PetscMax(rtol,stol);
533671f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
533771f87433Sdalcinl       /* safeguard: avoid oversolving */
533830058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
533971f87433Sdalcinl       stol = PetscMax(rtol,stol);
534071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
5341e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
534271f87433Sdalcinl   }
534371f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
534471f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
534571f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
534657622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
534771f87433Sdalcinl   PetscFunctionReturn(0);
534871f87433Sdalcinl }
534971f87433Sdalcinl 
5350d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
535171f87433Sdalcinl {
535271f87433Sdalcinl   PetscErrorCode ierr;
5353fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
535471f87433Sdalcinl   PCSide         pcside;
535571f87433Sdalcinl   Vec            lres;
535671f87433Sdalcinl 
535771f87433Sdalcinl   PetscFunctionBegin;
5358d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
53599e5d0892SLisandro Dalcin   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL);CHKERRQ(ierr);
536071dbe336SPeter Brune   kctx->norm_last = snes->norm;
536171f87433Sdalcinl   if (kctx->version == 1) {
53624f00ce20SMatthew G. Knepley     PC        pc;
53634f00ce20SMatthew G. Knepley     PetscBool isNone;
53644f00ce20SMatthew G. Knepley 
53654f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
53664f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
5367b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
53684f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
536971f87433Sdalcinl       /* KSP residual is true linear residual */
537071f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
537171f87433Sdalcinl     } else {
537271f87433Sdalcinl       /* KSP residual is preconditioned residual */
537371f87433Sdalcinl       /* compute true linear residual norm */
537471f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
537571f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
537671f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
537771f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
53786bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
537971f87433Sdalcinl     }
538071f87433Sdalcinl   }
538171f87433Sdalcinl   PetscFunctionReturn(0);
538271f87433Sdalcinl }
538371f87433Sdalcinl 
5384d4211eb9SBarry Smith /*@
5385d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
5386d4211eb9SBarry Smith 
5387d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
5388d4211eb9SBarry Smith 
5389d4211eb9SBarry Smith    Input Parameter:
5390d4211eb9SBarry Smith .  snes - the SNES context
5391d4211eb9SBarry Smith 
5392d4211eb9SBarry Smith    Output Parameter:
5393d4211eb9SBarry Smith .  ksp - the KSP context
5394d4211eb9SBarry Smith 
5395d4211eb9SBarry Smith    Notes:
5396d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
5397d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
5398d4211eb9SBarry Smith    PC contexts as well.
5399d4211eb9SBarry Smith 
5400d4211eb9SBarry Smith    Level: beginner
5401d4211eb9SBarry Smith 
5402d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
5403d4211eb9SBarry Smith @*/
5404d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
540571f87433Sdalcinl {
540671f87433Sdalcinl   PetscErrorCode ierr;
540771f87433Sdalcinl 
540871f87433Sdalcinl   PetscFunctionBegin;
5409d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5410d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
5411d4211eb9SBarry Smith 
5412d4211eb9SBarry Smith   if (!snes->ksp) {
5413d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
5414d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
54153bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
5416d4211eb9SBarry Smith 
5417d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
5418d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
5419a5c2985bSBarry Smith 
5420798534f6SMatthew G. Knepley     ierr = KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes);CHKERRQ(ierr);
542116413a6aSBarry Smith     ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr);
5422d4211eb9SBarry Smith   }
5423d4211eb9SBarry Smith   *ksp = snes->ksp;
542471f87433Sdalcinl   PetscFunctionReturn(0);
542571f87433Sdalcinl }
54266c699258SBarry Smith 
5427d4211eb9SBarry Smith 
5428af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
54296c699258SBarry Smith /*@
54302a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
54316c699258SBarry Smith 
54323f9fe445SBarry Smith    Logically Collective on SNES
54336c699258SBarry Smith 
54346c699258SBarry Smith    Input Parameters:
54352a808120SBarry Smith +  snes - the nonlinear solver context
54362a808120SBarry Smith -  dm - the dm, cannot be NULL
54376c699258SBarry Smith 
5438e03a659cSJed Brown    Notes:
5439e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
5440e03a659cSJed Brown    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
5441e03a659cSJed Brown    problems using the same function space.
5442e03a659cSJed Brown 
54436c699258SBarry Smith    Level: intermediate
54446c699258SBarry Smith 
54454c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
54466c699258SBarry Smith @*/
54477087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
54486c699258SBarry Smith {
54496c699258SBarry Smith   PetscErrorCode ierr;
5450345fed2cSBarry Smith   KSP            ksp;
5451942e3340SBarry Smith   DMSNES         sdm;
54526c699258SBarry Smith 
54536c699258SBarry Smith   PetscFunctionBegin;
54540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
54552a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
54562a808120SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5457942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
545851f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
5459942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
5460942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
5461f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
54626cab3a1bSJed Brown     }
5463dc822a44SJed Brown     ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
54646bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
54656cab3a1bSJed Brown   }
54666c699258SBarry Smith   snes->dm     = dm;
5467116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
5468f5af7f23SKarl Rupp 
5469345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
5470345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
5471f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
5472efd4aadfSBarry Smith   if (snes->npc) {
5473efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr);
5474efd4aadfSBarry Smith     ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr);
54752c155ee1SBarry Smith   }
54766c699258SBarry Smith   PetscFunctionReturn(0);
54776c699258SBarry Smith }
54786c699258SBarry Smith 
54796c699258SBarry Smith /*@
54806c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
54816c699258SBarry Smith 
54823f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
54836c699258SBarry Smith 
54846c699258SBarry Smith    Input Parameter:
54856c699258SBarry Smith . snes - the preconditioner context
54866c699258SBarry Smith 
54876c699258SBarry Smith    Output Parameter:
54886c699258SBarry Smith .  dm - the dm
54896c699258SBarry Smith 
54906c699258SBarry Smith    Level: intermediate
54916c699258SBarry Smith 
54924c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
54936c699258SBarry Smith @*/
54947087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
54956c699258SBarry Smith {
54966cab3a1bSJed Brown   PetscErrorCode ierr;
54976cab3a1bSJed Brown 
54986c699258SBarry Smith   PetscFunctionBegin;
54990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
55006cab3a1bSJed Brown   if (!snes->dm) {
5501ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
5502116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
55036cab3a1bSJed Brown   }
55046c699258SBarry Smith   *dm = snes->dm;
55056c699258SBarry Smith   PetscFunctionReturn(0);
55066c699258SBarry Smith }
55070807856dSBarry Smith 
550831823bd8SMatthew G Knepley /*@
5509be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
551031823bd8SMatthew G Knepley 
551131823bd8SMatthew G Knepley   Collective on SNES
551231823bd8SMatthew G Knepley 
551331823bd8SMatthew G Knepley   Input Parameters:
551431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
551531823bd8SMatthew G Knepley - pc   - the preconditioner object
551631823bd8SMatthew G Knepley 
551731823bd8SMatthew G Knepley   Notes:
5518be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
551931823bd8SMatthew G Knepley   to configure it using the API).
552031823bd8SMatthew G Knepley 
552131823bd8SMatthew G Knepley   Level: developer
552231823bd8SMatthew G Knepley 
55233ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
552431823bd8SMatthew G Knepley @*/
5525be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
552631823bd8SMatthew G Knepley {
552731823bd8SMatthew G Knepley   PetscErrorCode ierr;
552831823bd8SMatthew G Knepley 
552931823bd8SMatthew G Knepley   PetscFunctionBegin;
553031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
553131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
553231823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
553331823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
5534efd4aadfSBarry Smith   ierr     = SNESDestroy(&snes->npc);CHKERRQ(ierr);
5535efd4aadfSBarry Smith   snes->npc = pc;
5536efd4aadfSBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr);
553731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
553831823bd8SMatthew G Knepley }
553931823bd8SMatthew G Knepley 
554031823bd8SMatthew G Knepley /*@
5541be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
554231823bd8SMatthew G Knepley 
5543951fe5abSBarry Smith   Not Collective; but any changes to the obtained SNES object must be applied collectively
554431823bd8SMatthew G Knepley 
554531823bd8SMatthew G Knepley   Input Parameter:
554631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
554731823bd8SMatthew G Knepley 
554831823bd8SMatthew G Knepley   Output Parameter:
554931823bd8SMatthew G Knepley . pc - preconditioner context
555031823bd8SMatthew G Knepley 
5551b5badacbSBarry Smith   Options Database:
5552b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner
5553b5badacbSBarry Smith 
555495452b02SPatrick Sanan   Notes:
5555b5badacbSBarry Smith     If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created.
5556be95d8f1SBarry Smith 
5557951fe5abSBarry Smith     The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5558951fe5abSBarry Smith     SNES during SNESSetUp()
5559951fe5abSBarry Smith 
556031823bd8SMatthew G Knepley   Level: developer
556131823bd8SMatthew G Knepley 
5562951fe5abSBarry Smith .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate()
556331823bd8SMatthew G Knepley @*/
5564be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
556531823bd8SMatthew G Knepley {
556631823bd8SMatthew G Knepley   PetscErrorCode ierr;
5567a64e098fSPeter Brune   const char     *optionsprefix;
556831823bd8SMatthew G Knepley 
556931823bd8SMatthew G Knepley   PetscFunctionBegin;
557031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
557131823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
5572efd4aadfSBarry Smith   if (!snes->npc) {
5573efd4aadfSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr);
5574efd4aadfSBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr);
5575efd4aadfSBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
5576a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
5577efd4aadfSBarry Smith     ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr);
5578efd4aadfSBarry Smith     ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr);
5579efd4aadfSBarry Smith     ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr);
558031823bd8SMatthew G Knepley   }
5581efd4aadfSBarry Smith   *pc = snes->npc;
558231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
558331823bd8SMatthew G Knepley }
558431823bd8SMatthew G Knepley 
55853ad1a0b9SPatrick Farrell /*@
55863ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
55873ad1a0b9SPatrick Farrell 
55883ad1a0b9SPatrick Farrell   Not Collective
55893ad1a0b9SPatrick Farrell 
55903ad1a0b9SPatrick Farrell   Input Parameter:
55913ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
55923ad1a0b9SPatrick Farrell 
55933ad1a0b9SPatrick Farrell   Output Parameter:
55943ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
55953ad1a0b9SPatrick Farrell 
55963ad1a0b9SPatrick Farrell   Level: developer
55973ad1a0b9SPatrick Farrell 
55983ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
55993ad1a0b9SPatrick Farrell @*/
56003ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
56013ad1a0b9SPatrick Farrell {
56023ad1a0b9SPatrick Farrell   PetscFunctionBegin;
56033ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5604efd4aadfSBarry Smith   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
56053ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
56063ad1a0b9SPatrick Farrell }
56073ad1a0b9SPatrick Farrell 
5608c40d0f55SPeter Brune /*@
5609be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5610c40d0f55SPeter Brune 
5611c40d0f55SPeter Brune     Logically Collective on SNES
5612c40d0f55SPeter Brune 
5613c40d0f55SPeter Brune     Input Parameter:
5614c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5615c40d0f55SPeter Brune 
5616c40d0f55SPeter Brune     Output Parameter:
5617c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5618c40d0f55SPeter Brune .vb
56192d547940SBarry Smith       PC_LEFT - left preconditioning
56202d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5621c40d0f55SPeter Brune .ve
5622c40d0f55SPeter Brune 
5623c40d0f55SPeter Brune     Options Database Keys:
5624c40d0f55SPeter Brune .   -snes_pc_side <right,left>
5625c40d0f55SPeter Brune 
562695452b02SPatrick Sanan     Notes:
562795452b02SPatrick Sanan     SNESNRICHARDSON and SNESNCG only support left preconditioning.
56282d547940SBarry Smith 
5629c40d0f55SPeter Brune     Level: intermediate
5630c40d0f55SPeter Brune 
5631be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
5632c40d0f55SPeter Brune @*/
5633be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5634c40d0f55SPeter Brune {
5635c40d0f55SPeter Brune   PetscFunctionBegin;
5636c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5637c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
5638efd4aadfSBarry Smith   snes->npcside= side;
5639c40d0f55SPeter Brune   PetscFunctionReturn(0);
5640c40d0f55SPeter Brune }
5641c40d0f55SPeter Brune 
5642c40d0f55SPeter Brune /*@
5643be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5644c40d0f55SPeter Brune 
5645c40d0f55SPeter Brune     Not Collective
5646c40d0f55SPeter Brune 
5647c40d0f55SPeter Brune     Input Parameter:
5648c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5649c40d0f55SPeter Brune 
5650c40d0f55SPeter Brune     Output Parameter:
5651c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5652c40d0f55SPeter Brune .vb
56532d547940SBarry Smith       PC_LEFT - left preconditioning
56542d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5655c40d0f55SPeter Brune .ve
5656c40d0f55SPeter Brune 
5657c40d0f55SPeter Brune     Level: intermediate
5658c40d0f55SPeter Brune 
5659be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
5660c40d0f55SPeter Brune @*/
5661be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5662c40d0f55SPeter Brune {
5663c40d0f55SPeter Brune   PetscFunctionBegin;
5664c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5665c40d0f55SPeter Brune   PetscValidPointer(side,2);
5666efd4aadfSBarry Smith   *side = snes->npcside;
5667c40d0f55SPeter Brune   PetscFunctionReturn(0);
5668c40d0f55SPeter Brune }
5669c40d0f55SPeter Brune 
56709e764e56SPeter Brune /*@
56717601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
56729e764e56SPeter Brune 
56739e764e56SPeter Brune   Collective on SNES
56749e764e56SPeter Brune 
56759e764e56SPeter Brune   Input Parameters:
56769e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
56779e764e56SPeter Brune - linesearch   - the linesearch object
56789e764e56SPeter Brune 
56799e764e56SPeter Brune   Notes:
56807601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
56819e764e56SPeter Brune   to configure it using the API).
56829e764e56SPeter Brune 
56839e764e56SPeter Brune   Level: developer
56849e764e56SPeter Brune 
56857601faf0SJed Brown .seealso: SNESGetLineSearch()
56869e764e56SPeter Brune @*/
56877601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
56889e764e56SPeter Brune {
56899e764e56SPeter Brune   PetscErrorCode ierr;
56909e764e56SPeter Brune 
56919e764e56SPeter Brune   PetscFunctionBegin;
56929e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5693f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
56949e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
56959e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5696f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5697f5af7f23SKarl Rupp 
56989e764e56SPeter Brune   snes->linesearch = linesearch;
5699f5af7f23SKarl Rupp 
57003bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
57019e764e56SPeter Brune   PetscFunctionReturn(0);
57029e764e56SPeter Brune }
57039e764e56SPeter Brune 
5704a34ceb2aSJed Brown /*@
57057601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
57068141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
57079e764e56SPeter Brune 
57089e764e56SPeter Brune   Not Collective
57099e764e56SPeter Brune 
57109e764e56SPeter Brune   Input Parameter:
57119e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
57129e764e56SPeter Brune 
57139e764e56SPeter Brune   Output Parameter:
57149e764e56SPeter Brune . linesearch - linesearch context
57159e764e56SPeter Brune 
5716162e0bf5SPeter Brune   Level: beginner
57179e764e56SPeter Brune 
5718162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
57199e764e56SPeter Brune @*/
57207601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
57219e764e56SPeter Brune {
57229e764e56SPeter Brune   PetscErrorCode ierr;
57239e764e56SPeter Brune   const char     *optionsprefix;
57249e764e56SPeter Brune 
57259e764e56SPeter Brune   PetscFunctionBegin;
57269e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
57279e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
57289e764e56SPeter Brune   if (!snes->linesearch) {
57299e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
573082f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5731f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5732b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
57339e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
57343bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
57359e764e56SPeter Brune   }
57369e764e56SPeter Brune   *linesearch = snes->linesearch;
57379e764e56SPeter Brune   PetscFunctionReturn(0);
57389e764e56SPeter Brune }
5739