xref: /petsc/src/snes/interface/snes.c (revision 2479783c2e116355bf0a94b8df33cab7c85224fa)
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 
35936851e7fSLois Curfman McInnes    Level: beginner
36036851e7fSLois Curfman McInnes 
361b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
3629b94acceSBarry Smith @*/
3637087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
3649b94acceSBarry Smith {
365fa9f3622SBarry Smith   SNESKSPEW      *kctx;
366dfbe8321SBarry Smith   PetscErrorCode ierr;
36794b7f48cSBarry Smith   KSP            ksp;
3687f1410a3SPeter Brune   SNESLineSearch linesearch;
36972a02f06SBarry Smith   PetscBool      iascii,isstring,isbinary,isdraw;
3702d53ad75SBarry Smith   DMSNES         dmsnes;
371e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
372536b137fSBarry Smith   PetscBool      issaws;
373bfb97211SBarry Smith #endif
3749b94acceSBarry Smith 
3753a40ed3dSBarry Smith   PetscFunctionBegin;
3760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3773050cee2SBarry Smith   if (!viewer) {
378ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
3793050cee2SBarry Smith   }
3800700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
381c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
38274679c65SBarry Smith 
383251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
384251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
38555849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
38672a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
387e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
388536b137fSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
389bfb97211SBarry Smith #endif
39032077d6dSBarry Smith   if (iascii) {
391dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
3928404b7f3SBarry Smith     DM               dm;
3938404b7f3SBarry Smith     PetscErrorCode   (*cJ)(SNES,Vec,Mat,Mat,void*);
3948404b7f3SBarry Smith     void             *ctx;
395789d8953SBarry Smith     const char       *pre = "";
396dc0571f2SMatthew G. Knepley 
397dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr);
398fce1e034SJed Brown     if (!snes->setupcalled) {
399fce1e034SJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr);
400fce1e034SJed Brown     }
401e7788613SBarry Smith     if (snes->ops->view) {
402b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
403e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
404b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
4050ef38995SBarry Smith     }
40677431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
40757622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr);
408efd4aadfSBarry Smith     if (snes->usesksp) {
40977431f27SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
410efd4aadfSBarry Smith     }
41177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
412dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
413dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
41417fe4bdfSPeter Brune     if (snes->gridsequence) {
41517fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
41617fe4bdfSPeter Brune     }
4179b94acceSBarry Smith     if (snes->ksp_ewconv) {
418fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
4199b94acceSBarry Smith       if (kctx) {
42077431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
42157622a8eSBarry 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);
42257622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
4239b94acceSBarry Smith       }
4249b94acceSBarry Smith     }
425eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
426eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
427eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
428eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
429eb1f6c34SBarry Smith     }
430eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
431eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
432eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
43342f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
434eb1f6c34SBarry Smith     }
4358404b7f3SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4368404b7f3SBarry Smith     ierr = DMSNESGetJacobian(dm,&cJ,&ctx);CHKERRQ(ierr);
437789d8953SBarry Smith     if (snes->mf_operator) {
438789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing\n");CHKERRQ(ierr);
439789d8953SBarry Smith       pre  = "Preconditioning ";
440789d8953SBarry Smith     }
4418404b7f3SBarry Smith     if (cJ == SNESComputeJacobianDefault) {
442789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences one column at a time\n",pre);CHKERRQ(ierr);
4438404b7f3SBarry Smith     } else if (cJ == SNESComputeJacobianDefaultColor) {
444789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using finite differences with coloring\n",pre);CHKERRQ(ierr);
445789d8953SBarry Smith     /* it slightly breaks data encapsulation for access the DMDA information directly */
446789d8953SBarry Smith     } else if (cJ == SNESComputeJacobian_DMDA) {
447789d8953SBarry Smith       MatFDColoring fdcoloring;
448789d8953SBarry Smith       ierr = PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring);CHKERRQ(ierr);
449789d8953SBarry Smith       if (fdcoloring) {
450789d8953SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using colored finite differences on a DMDA\n",pre);CHKERRQ(ierr);
451789d8953SBarry Smith       } else {
452789d8953SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  %sJacobian is built using a DMDA local Jacobian\n",pre);CHKERRQ(ierr);
453789d8953SBarry Smith       }
454789d8953SBarry Smith     } else if (snes->mf) {
455789d8953SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is applied matrix-free with differencing, no explict Jacobian\n");CHKERRQ(ierr);
4568404b7f3SBarry Smith     }
4570f5bd95cSBarry Smith   } else if (isstring) {
458317d6ea6SBarry Smith     const char *type;
459454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
46036a9e3b9SBarry Smith     ierr = PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type);CHKERRQ(ierr);
46136a9e3b9SBarry Smith     if (snes->ops->view) {ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);}
46255849f57SBarry Smith   } else if (isbinary) {
46355849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
46455849f57SBarry Smith     MPI_Comm    comm;
46555849f57SBarry Smith     PetscMPIInt rank;
46655849f57SBarry Smith     char        type[256];
46755849f57SBarry Smith 
46855849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
46955849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
47055849f57SBarry Smith     if (!rank) {
471f253e43cSLisandro Dalcin       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
47289d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
473f253e43cSLisandro Dalcin       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR);CHKERRQ(ierr);
47455849f57SBarry Smith     }
47555849f57SBarry Smith     if (snes->ops->view) {
47655849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
47755849f57SBarry Smith     }
47872a02f06SBarry Smith   } else if (isdraw) {
47972a02f06SBarry Smith     PetscDraw draw;
48072a02f06SBarry Smith     char      str[36];
48189fd9fafSBarry Smith     PetscReal x,y,bottom,h;
48272a02f06SBarry Smith 
48372a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
48472a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
485a126751eSBarry Smith     ierr   = PetscStrncpy(str,"SNES: ",sizeof(str));CHKERRQ(ierr);
486a126751eSBarry Smith     ierr   = PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str));CHKERRQ(ierr);
48751fa3d41SBarry Smith     ierr   = PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
48889fd9fafSBarry Smith     bottom = y - h;
48972a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
490c4646bacSPeter Brune     if (snes->ops->view) {
491c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
492c4646bacSPeter Brune     }
493e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
494536b137fSBarry Smith   } else if (issaws) {
495d45a07a7SBarry Smith     PetscMPIInt rank;
4962657e9d9SBarry Smith     const char *name;
497d45a07a7SBarry Smith 
4982657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
499d45a07a7SBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
500d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
501d45a07a7SBarry Smith       char       dir[1024];
502d45a07a7SBarry Smith 
503e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
5042657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
5052657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
506bfb97211SBarry Smith       if (!snes->conv_hist) {
507a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
508bfb97211SBarry Smith       }
5092657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
5102657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
511f05ece33SBarry Smith     }
512bfb97211SBarry Smith #endif
51372a02f06SBarry Smith   }
51472a02f06SBarry Smith   if (snes->linesearch) {
5157601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
51685928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
51772a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
51885928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
51919bcc07fSBarry Smith   }
520efd4aadfSBarry Smith   if (snes->npc && snes->usesnpc) {
52185928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
522efd4aadfSBarry Smith     ierr = SNESView(snes->npc, viewer);CHKERRQ(ierr);
52385928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5244a0c5b0cSMatthew G Knepley   }
5252d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
5262d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
5272d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
5282d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5292c155ee1SBarry Smith   if (snes->usesksp) {
5302c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
53185928a98SStefano Zampini     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
53294b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
53385928a98SStefano Zampini     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
5342c155ee1SBarry Smith   }
53572a02f06SBarry Smith   if (isdraw) {
53672a02f06SBarry Smith     PetscDraw draw;
53772a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
53872a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
5397f1410a3SPeter Brune   }
5403a40ed3dSBarry Smith   PetscFunctionReturn(0);
5419b94acceSBarry Smith }
5429b94acceSBarry Smith 
54376b2cf59SMatthew Knepley /*
54476b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
54576b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
54676b2cf59SMatthew Knepley */
54776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
548a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
5496849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
55076b2cf59SMatthew Knepley 
551ac226902SBarry Smith /*@C
55276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
55376b2cf59SMatthew Knepley 
55476b2cf59SMatthew Knepley   Not Collective
55576b2cf59SMatthew Knepley 
55676b2cf59SMatthew Knepley   Input Parameter:
55776b2cf59SMatthew Knepley . snescheck - function that checks for options
55876b2cf59SMatthew Knepley 
55976b2cf59SMatthew Knepley   Level: developer
56076b2cf59SMatthew Knepley 
56176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
56276b2cf59SMatthew Knepley @*/
5637087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
56476b2cf59SMatthew Knepley {
56576b2cf59SMatthew Knepley   PetscFunctionBegin;
566f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
56776b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
56876b2cf59SMatthew Knepley   PetscFunctionReturn(0);
56976b2cf59SMatthew Knepley }
57076b2cf59SMatthew Knepley 
57125acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
572aa3661deSLisandro Dalcin 
573ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
574aa3661deSLisandro Dalcin {
575aa3661deSLisandro Dalcin   Mat            J;
576aa3661deSLisandro Dalcin   PetscErrorCode ierr;
577895c21f2SBarry Smith   MatNullSpace   nullsp;
578aa3661deSLisandro Dalcin 
579aa3661deSLisandro Dalcin   PetscFunctionBegin;
5800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
581aa3661deSLisandro Dalcin 
58298613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
58398613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
5842a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
58598613b67SLisandro Dalcin   }
58698613b67SLisandro Dalcin 
587aa3661deSLisandro Dalcin   if (version == 1) {
588aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
58998613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5909c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
591aa3661deSLisandro Dalcin   } else if (version == 2) {
592e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
593570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16)
594aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
595aa3661deSLisandro Dalcin #else
596*2479783cSJose E. Roman     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)");
597aa3661deSLisandro Dalcin #endif
598*2479783cSJose E. Roman   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2");
599aa3661deSLisandro Dalcin 
600895c21f2SBarry Smith   /* attach any user provided null space that was on Amat to the newly created matrix free matrix */
601895c21f2SBarry Smith   if (snes->jacobian) {
602895c21f2SBarry Smith     ierr = MatGetNullSpace(snes->jacobian,&nullsp);CHKERRQ(ierr);
603895c21f2SBarry Smith     if (nullsp) {
604895c21f2SBarry Smith       ierr = MatSetNullSpace(J,nullsp);CHKERRQ(ierr);
605895c21f2SBarry Smith     }
606895c21f2SBarry Smith   }
607895c21f2SBarry Smith 
608aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
609d3462f78SMatthew Knepley   if (hasOperator) {
6103232da50SPeter Brune 
611aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
612aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
6139e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);
614aa3661deSLisandro Dalcin   } else {
615aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
6163232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
617efd4aadfSBarry Smith     if ((snes->npcside== PC_LEFT) && snes->npc) {
6189e5d0892SLisandro Dalcin       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,NULL,NULL,NULL);CHKERRQ(ierr);}
619172a4300SPeter Brune     } else {
620789d8953SBarry Smith       KSP       ksp;
621789d8953SBarry Smith       PC        pc;
622789d8953SBarry Smith       PetscBool match;
623789d8953SBarry Smith 
6249e5d0892SLisandro Dalcin       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL);CHKERRQ(ierr);
625aa3661deSLisandro Dalcin       /* Force no preconditioner */
626aa3661deSLisandro Dalcin       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
627aa3661deSLisandro Dalcin       ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
628251f4c67SDmitry Karpeev       ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
629aa3661deSLisandro Dalcin       if (!match) {
630aa3661deSLisandro Dalcin         ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
631aa3661deSLisandro Dalcin         ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
632aa3661deSLisandro Dalcin       }
633aa3661deSLisandro Dalcin     }
634789d8953SBarry Smith   }
6356bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
636aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
637aa3661deSLisandro Dalcin }
638aa3661deSLisandro Dalcin 
639dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
640dfe15315SJed Brown {
641dfe15315SJed Brown   SNES           snes = (SNES)ctx;
642dfe15315SJed Brown   PetscErrorCode ierr;
6430298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
644dfe15315SJed Brown 
645dfe15315SJed Brown   PetscFunctionBegin;
64616ebb321SJed Brown   if (PetscLogPrintInfo) {
64716ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
64816ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
64916ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
65016ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
65116ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
65216ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
65316ebb321SJed Brown   }
654dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
655dfe15315SJed Brown   else {
656dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
657dfe15315SJed Brown     Xfine = Xfine_named;
658dfe15315SJed Brown   }
659dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
660907f5c5aSLawrence Mitchell   if (Inject) {
661907f5c5aSLawrence Mitchell     ierr = MatRestrict(Inject,Xfine,Xcoarse);CHKERRQ(ierr);
662907f5c5aSLawrence Mitchell   } else {
663dfe15315SJed Brown     ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
664dfe15315SJed Brown     ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
665907f5c5aSLawrence Mitchell   }
666dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
667dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
668dfe15315SJed Brown   PetscFunctionReturn(0);
669dfe15315SJed Brown }
670dfe15315SJed Brown 
67116ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
67216ebb321SJed Brown {
67316ebb321SJed Brown   PetscErrorCode ierr;
67416ebb321SJed Brown 
67516ebb321SJed Brown   PetscFunctionBegin;
67616ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
67716ebb321SJed Brown   PetscFunctionReturn(0);
67816ebb321SJed Brown }
67916ebb321SJed Brown 
680a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
681a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
68223ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
683caa4e7f2SJed Brown {
684caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
685caa4e7f2SJed Brown   PetscErrorCode ierr;
6860298fd71SBarry Smith   Vec            X,Xnamed = NULL;
687dfe15315SJed Brown   DM             dmsave;
6884e269d77SPeter Brune   void           *ctxsave;
68925ce1634SJed Brown   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL;
690caa4e7f2SJed Brown 
691caa4e7f2SJed Brown   PetscFunctionBegin;
692dfe15315SJed Brown   dmsave = snes->dm;
693dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
694dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
695dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
696dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
697dfe15315SJed Brown     X    = Xnamed;
6980298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
6994e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
7008d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
7019e5d0892SLisandro Dalcin       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
702dfe15315SJed Brown     }
7034e269d77SPeter Brune   }
7044dde8bb0SMatthew G. Knepley   /* Make sure KSP DM has the Jacobian computation routine */
7054dde8bb0SMatthew G. Knepley   {
7064dde8bb0SMatthew G. Knepley     DMSNES sdm;
7074e269d77SPeter Brune 
7084dde8bb0SMatthew G. Knepley     ierr = DMGetDMSNES(snes->dm, &sdm);CHKERRQ(ierr);
7094dde8bb0SMatthew G. Knepley     if (!sdm->ops->computejacobian) {
7104dde8bb0SMatthew G. Knepley       ierr = DMCopyDMSNES(dmsave, snes->dm);CHKERRQ(ierr);
7114dde8bb0SMatthew G. Knepley     }
7124dde8bb0SMatthew G. Knepley   }
7132b93b426SMatthew G. Knepley   /* Compute the operators */
714d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
7152b93b426SMatthew G. Knepley   /* Put the previous context back */
7168d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
7170298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
7184e269d77SPeter Brune   }
7194e269d77SPeter Brune 
7202b93b426SMatthew G. Knepley   if (Xnamed) {ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);}
721dfe15315SJed Brown   snes->dm = dmsave;
722caa4e7f2SJed Brown   PetscFunctionReturn(0);
723caa4e7f2SJed Brown }
724caa4e7f2SJed Brown 
7256cab3a1bSJed Brown /*@
7266cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
7276cab3a1bSJed Brown 
7286cab3a1bSJed Brown    Collective
7296cab3a1bSJed Brown 
7306cab3a1bSJed Brown    Input Arguments:
7316cab3a1bSJed Brown .  snes - snes to configure
7326cab3a1bSJed Brown 
7336cab3a1bSJed Brown    Level: developer
7346cab3a1bSJed Brown 
7356cab3a1bSJed Brown .seealso: SNESSetUp()
7366cab3a1bSJed Brown @*/
7376cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
7386cab3a1bSJed Brown {
7396cab3a1bSJed Brown   PetscErrorCode ierr;
7406cab3a1bSJed Brown   DM             dm;
741942e3340SBarry Smith   DMSNES         sdm;
7426cab3a1bSJed Brown 
7436cab3a1bSJed Brown   PetscFunctionBegin;
7446cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
745942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
74658b371f3SBarry Smith   if (!snes->jacobian && snes->mf) {
7476cab3a1bSJed Brown     Mat  J;
7486cab3a1bSJed Brown     void *functx;
7496cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
7506cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
7516cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
7520298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
7539e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,J,J,NULL,NULL);CHKERRQ(ierr);
7546cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
755caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
7566cab3a1bSJed Brown     Mat J,B;
7576cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
7586cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
7596cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
760b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
76106f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
7620298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
7636cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
7646cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
765caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
7668cda7954SMatthew G. Knepley     PetscErrorCode (*nspconstr)(DM, PetscInt, PetscInt, MatNullSpace *);
7671ba9b98eSMatthew G. Knepley     PetscDS          prob;
7686cab3a1bSJed Brown     Mat              J, B;
7694f3e65b0SMatthew G. Knepley     MatNullSpace     nullspace = NULL;
7701ba9b98eSMatthew G. Knepley     PetscBool        hasPrec   = PETSC_FALSE;
7714f3e65b0SMatthew G. Knepley     PetscInt         Nf;
7721ba9b98eSMatthew G. Knepley 
7736cab3a1bSJed Brown     J    = snes->jacobian;
7741ba9b98eSMatthew G. Knepley     ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
7751ba9b98eSMatthew G. Knepley     if (prob) {ierr = PetscDSHasJacobianPreconditioner(prob, &hasPrec);CHKERRQ(ierr);}
776ec9a985fSMatthew G. Knepley     if (J)            {ierr = PetscObjectReference((PetscObject) J);CHKERRQ(ierr);}
777ec9a985fSMatthew G. Knepley     else if (hasPrec) {ierr = DMCreateMatrix(snes->dm, &J);CHKERRQ(ierr);}
778b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm, &B);CHKERRQ(ierr);
7794f3e65b0SMatthew G. Knepley     ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
7804f3e65b0SMatthew G. Knepley     ierr = DMGetNullSpaceConstructor(snes->dm, Nf, &nspconstr);CHKERRQ(ierr);
7818cda7954SMatthew G. Knepley     if (nspconstr) (*nspconstr)(snes->dm, Nf, Nf, &nullspace);
7824f3e65b0SMatthew G. Knepley     ierr = MatSetNullSpace(B, nullspace);CHKERRQ(ierr);
7834f3e65b0SMatthew G. Knepley     ierr = MatNullSpaceDestroy(&nullspace);CHKERRQ(ierr);
7840298fd71SBarry Smith     ierr = SNESSetJacobian(snes, J ? J : B, B, NULL, NULL);CHKERRQ(ierr);
7851ba9b98eSMatthew G. Knepley     ierr = MatDestroy(&J);CHKERRQ(ierr);
7866cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
7876cab3a1bSJed Brown   }
788caa4e7f2SJed Brown   {
789caa4e7f2SJed Brown     KSP ksp;
790caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
791caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
79216ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
793caa4e7f2SJed Brown   }
7946cab3a1bSJed Brown   PetscFunctionReturn(0);
7956cab3a1bSJed Brown }
7966cab3a1bSJed Brown 
797fde5950dSBarry Smith /*@C
798fde5950dSBarry Smith    SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
799fde5950dSBarry Smith 
800fde5950dSBarry Smith    Collective on SNES
801fde5950dSBarry Smith 
802fde5950dSBarry Smith    Input Parameters:
803fde5950dSBarry Smith +  snes - SNES object you wish to monitor
804fde5950dSBarry Smith .  name - the monitor type one is seeking
805fde5950dSBarry Smith .  help - message indicating what monitoring is done
806fde5950dSBarry Smith .  manual - manual page for the monitor
807fde5950dSBarry Smith .  monitor - the monitor function
808fde5950dSBarry 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
809fde5950dSBarry Smith 
810fde5950dSBarry Smith    Level: developer
811fde5950dSBarry Smith 
812fde5950dSBarry Smith .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
813fde5950dSBarry Smith           PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
814fde5950dSBarry Smith           PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
815fde5950dSBarry Smith           PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
816fde5950dSBarry Smith           PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
817fde5950dSBarry Smith           PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
818fde5950dSBarry Smith           PetscOptionsFList(), PetscOptionsEList()
819fde5950dSBarry Smith @*/
820d43b4f6eSBarry Smith PetscErrorCode  SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*))
821fde5950dSBarry Smith {
822fde5950dSBarry Smith   PetscErrorCode    ierr;
823fde5950dSBarry Smith   PetscViewer       viewer;
824fde5950dSBarry Smith   PetscViewerFormat format;
825fde5950dSBarry Smith   PetscBool         flg;
826fde5950dSBarry Smith 
827fde5950dSBarry Smith   PetscFunctionBegin;
82816413a6aSBarry Smith   ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg);CHKERRQ(ierr);
829fde5950dSBarry Smith   if (flg) {
830d43b4f6eSBarry Smith     PetscViewerAndFormat *vf;
831d43b4f6eSBarry Smith     ierr = PetscViewerAndFormatCreate(viewer,format,&vf);CHKERRQ(ierr);
832d43b4f6eSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
833fde5950dSBarry Smith     if (monitorsetup) {
834d43b4f6eSBarry Smith       ierr = (*monitorsetup)(snes,vf);CHKERRQ(ierr);
835fde5950dSBarry Smith     }
836d43b4f6eSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);CHKERRQ(ierr);
837fde5950dSBarry Smith   }
838fde5950dSBarry Smith   PetscFunctionReturn(0);
839fde5950dSBarry Smith }
840fde5950dSBarry Smith 
8419b94acceSBarry Smith /*@
84294b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
8439b94acceSBarry Smith 
844c7afd0dbSLois Curfman McInnes    Collective on SNES
845c7afd0dbSLois Curfman McInnes 
8469b94acceSBarry Smith    Input Parameter:
8479b94acceSBarry Smith .  snes - the SNES context
8489b94acceSBarry Smith 
84936851e7fSLois Curfman McInnes    Options Database Keys:
850722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
85182738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
85282738288SBarry Smith                 of the change in the solution between steps
85370441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
854b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
855e4d06f11SPatrick Farrell .  -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence
856be5caee7SBarry Smith .  -snes_force_iteration <force> - force SNESSolve() to take at least one iteration
857b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
858b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
8594839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
860ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
861a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
8623d5a8a6aSBarry Smith .  -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve()
863e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
8643d5a8a6aSBarry Smith .  -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve()
865b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
8662492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
86782738288SBarry Smith                                solver; hence iterations will continue until max_it
8681fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
86982738288SBarry Smith                                of convergence test
870fde5950dSBarry Smith .  -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout
871fde5950dSBarry Smith .  -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration
872fde5950dSBarry Smith .  -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration
873fde5950dSBarry Smith .  -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration
8744619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
875459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
876e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
877e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
8785968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
879b5badacbSBarry Smith .  -snes_converged_reason - print the reason for convergence/divergence after each solve
880b5badacbSBarry Smith -  -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner
88182738288SBarry Smith 
88282738288SBarry Smith     Options Database for Eisenstat-Walker method:
883fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
8844b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
88536851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
88636851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
88736851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
88836851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
88936851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
89036851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
89182738288SBarry Smith 
89211ca99fdSLois Curfman McInnes    Notes:
893ec5066bdSBarry Smith    To see all options, run your program with the -help option or consult the users manual
894ec5066bdSBarry Smith 
895ec5066bdSBarry Smith    Notes:
896ec5066bdSBarry Smith       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly with
897ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
89883e2fdc7SBarry Smith 
89936851e7fSLois Curfman McInnes    Level: beginner
90036851e7fSLois Curfman McInnes 
901ec5066bdSBarry Smith .seealso: SNESSetOptionsPrefix(), SNESResetFromOptions(), SNES, SNESCreate()
9029b94acceSBarry Smith @*/
9037087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
9049b94acceSBarry Smith {
9058afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
906d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
90704d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
90885385478SLisandro Dalcin   const char     *convtests[] = {"default","skip"};
90985385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
910e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
91185385478SLisandro Dalcin   PetscErrorCode ierr;
912c40d0f55SPeter Brune   PCSide         pcside;
913a64e098fSPeter Brune   const char     *optionsprefix;
9149b94acceSBarry Smith 
9153a40ed3dSBarry Smith   PetscFunctionBegin;
9160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9170f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
9183194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
919639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
920a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
921d64ed03dSBarry Smith   if (flg) {
922186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
9237adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
924186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
925d64ed03dSBarry Smith   }
92694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
92794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
928186905e3SBarry Smith 
92994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
930e4d06f11SPatrick Farrell   ierr = PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL);CHKERRQ(ierr);
9310298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
9320298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
9330298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
9340298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
9350298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
9360d6f27a8SBarry Smith   ierr = PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL);CHKERRQ(ierr);
937b351a90bSFande Kong   ierr = PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL);CHKERRQ(ierr);
93885385478SLisandro Dalcin 
939a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
940a8054027SBarry Smith   if (flg) {
9413d5a8a6aSBarry 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");
942a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
943a8054027SBarry Smith   }
9449590daa0SBarry Smith   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
94537ec4e1aSPeter Brune   if (flg) {
94637ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
94737ec4e1aSPeter Brune   }
948e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
949e35cf81dSBarry Smith   if (flg) {
9503d5a8a6aSBarry 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");
951e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
952e35cf81dSBarry Smith   }
9539590daa0SBarry Smith   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
95437ec4e1aSPeter Brune   if (flg) {
95537ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
95637ec4e1aSPeter Brune   }
95737ec4e1aSPeter Brune 
958efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
959efd51863SBarry Smith   if (flg) {
960efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
961efd51863SBarry Smith   }
962a8054027SBarry Smith 
96385385478SLisandro Dalcin   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
96485385478SLisandro Dalcin   if (flg) {
96585385478SLisandro Dalcin     switch (indx) {
9668d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
967e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr);    break;
96885385478SLisandro Dalcin     }
96985385478SLisandro Dalcin   }
97085385478SLisandro Dalcin 
971365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
972365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
973fdacfa88SPeter Brune 
97447073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
97547073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
976186905e3SBarry Smith 
97785385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
97885385478SLisandro Dalcin 
9790298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
980186905e3SBarry Smith 
98194ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
98294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
98394ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
98494ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
98594ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
98694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
98794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
988186905e3SBarry Smith 
98990d69ab7SBarry Smith   flg  = PETSC_FALSE;
9908afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
9918afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
992eabae89aSBarry Smith 
993fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,NULL);CHKERRQ(ierr);
994fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL);CHKERRQ(ierr);
995fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL);CHKERRQ(ierr);
996eabae89aSBarry Smith 
997fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp);CHKERRQ(ierr);
998fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL);CHKERRQ(ierr);
999fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL);CHKERRQ(ierr);
1000fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL);CHKERRQ(ierr);
1001fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL);CHKERRQ(ierr);
1002fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL);CHKERRQ(ierr);
1003fde5950dSBarry Smith   ierr = SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL);CHKERRQ(ierr);
10042db13446SMatthew G. Knepley 
1005589a23caSBarry Smith   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);CHKERRQ(ierr);
10065180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
10075180491cSLisandro Dalcin 
100890d69ab7SBarry Smith   flg  = PETSC_FALSE;
10090298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr);
1010459f5d12SBarry Smith   if (flg) {
1011d96771aaSLisandro Dalcin     PetscDrawLG ctx;
1012459f5d12SBarry Smith 
10136ba87a44SLisandro Dalcin     ierr = SNESMonitorLGCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
1014d96771aaSLisandro Dalcin     ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);CHKERRQ(ierr);
1015459f5d12SBarry Smith   }
101690d69ab7SBarry Smith   flg  = PETSC_FALSE;
10170298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
1018459f5d12SBarry Smith   if (flg) {
1019459f5d12SBarry Smith     PetscViewer ctx;
1020e24b481bSBarry Smith 
10216ba87a44SLisandro Dalcin     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);CHKERRQ(ierr);
1022459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
1023459f5d12SBarry Smith   }
10242e7541e6SPeter Brune 
102590d69ab7SBarry Smith   flg  = PETSC_FALSE;
10268d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
10274b27c08aSLois Curfman McInnes   if (flg) {
10286cab3a1bSJed Brown     void    *functx;
1029b1f624c7SBarry Smith     DM      dm;
1030b1f624c7SBarry Smith     DMSNES  sdm;
1031b1f624c7SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1032b1f624c7SBarry Smith     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
1033b1f624c7SBarry Smith     sdm->jacobianctx = NULL;
10340298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
10358d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
1036ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
10379b94acceSBarry Smith   }
1038639f9d9dSBarry Smith 
103944848bc4SPeter Brune   flg  = PETSC_FALSE;
10408d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
104197584545SPeter Brune   if (flg) {
10428d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
104397584545SPeter Brune   }
104497584545SPeter Brune 
104597584545SPeter Brune   flg  = PETSC_FALSE;
10468d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
104744848bc4SPeter Brune   if (flg) {
1048c52e227fSPeter Brune     DM             dm;
1049c52e227fSPeter Brune     DMSNES         sdm;
1050c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1051aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
1052aace71b7SPeter Brune     sdm->jacobianctx = NULL;
10539e5d0892SLisandro Dalcin     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
105444848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
105544848bc4SPeter Brune   }
105644848bc4SPeter Brune 
1057aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
1058f871313dSBarry 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);
1059d8f46077SPeter Brune   if (flg && snes->mf_operator) {
1060a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
1061d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
1062a8248277SBarry Smith   }
1063aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
1064f871313dSBarry Smith   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
1065d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
10669e5d0892SLisandro Dalcin   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL);CHKERRQ(ierr);
1067d28543b3SPeter Brune 
1068c40d0f55SPeter Brune   flg  = PETSC_FALSE;
1069be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
1070be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
1071be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
1072c40d0f55SPeter Brune 
1073e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
10748a70d858SHong Zhang   /*
10758a70d858SHong Zhang     Publish convergence information using SAWs
10768a70d858SHong Zhang   */
10778a70d858SHong Zhang   flg  = PETSC_FALSE;
10788a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
10798a70d858SHong Zhang   if (flg) {
10808a70d858SHong Zhang     void *ctx;
10818a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
10828a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
10838a70d858SHong Zhang   }
10848a70d858SHong Zhang #endif
10858a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
1086b90c6cbeSBarry Smith   {
1087b90c6cbeSBarry Smith   PetscBool set;
1088b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
10898a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
1090b90c6cbeSBarry Smith   if (set) {
1091e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
1092b90c6cbeSBarry Smith   }
1093b90c6cbeSBarry Smith   }
1094b90c6cbeSBarry Smith #endif
1095b90c6cbeSBarry Smith 
109676b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
109776b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
109876b2cf59SMatthew Knepley   }
109976b2cf59SMatthew Knepley 
1100e7788613SBarry Smith   if (snes->ops->setfromoptions) {
1101e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
1102639f9d9dSBarry Smith   }
11035d973c19SBarry Smith 
11045d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
11050633abcbSJed Brown   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes);CHKERRQ(ierr);
1106b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
11074bbc92c1SBarry Smith 
1108d8d34be6SBarry Smith   if (snes->linesearch) {
11097601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
1110f1c6b773SPeter Brune     ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
1111d8d34be6SBarry Smith   }
11129e764e56SPeter Brune 
11136aa5e7e9SBarry Smith   if (snes->usesksp) {
11146991f827SBarry Smith     if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
11156991f827SBarry Smith     ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
11166991f827SBarry Smith     ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
11176aa5e7e9SBarry Smith   }
11186991f827SBarry Smith 
1119b5badacbSBarry Smith   /* if user has set the SNES NPC type via options database, create it. */
112051e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
1121c5929fdfSBarry Smith   ierr = PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
1122efd4aadfSBarry Smith   if (pcset && (!snes->npc)) {
1123efd4aadfSBarry Smith     ierr = SNESGetNPC(snes, &snes->npc);CHKERRQ(ierr);
112451e86f29SPeter Brune   }
1125b5badacbSBarry Smith   if (snes->npc) {
1126b5badacbSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
1127b5badacbSBarry Smith   }
1128b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled++;
1129b3cd9a81SMatthew G. Knepley   PetscFunctionReturn(0);
1130b3cd9a81SMatthew G. Knepley }
1131b3cd9a81SMatthew G. Knepley 
1132b3cd9a81SMatthew G. Knepley /*@
1133b3cd9a81SMatthew G. Knepley    SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options
1134b3cd9a81SMatthew G. Knepley 
1135b3cd9a81SMatthew G. Knepley    Collective on SNES
1136b3cd9a81SMatthew G. Knepley 
1137b3cd9a81SMatthew G. Knepley    Input Parameter:
1138b3cd9a81SMatthew G. Knepley .  snes - the SNES context
1139b3cd9a81SMatthew G. Knepley 
1140b3cd9a81SMatthew G. Knepley    Level: beginner
1141b3cd9a81SMatthew G. Knepley 
1142b3cd9a81SMatthew G. Knepley .seealso: SNESSetFromOptions(), SNESSetOptionsPrefix()
1143b3cd9a81SMatthew G. Knepley @*/
1144b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes)
1145b3cd9a81SMatthew G. Knepley {
1146b3cd9a81SMatthew G. Knepley   PetscErrorCode ierr;
1147b3cd9a81SMatthew G. Knepley 
1148b3cd9a81SMatthew G. Knepley   PetscFunctionBegin;
1149b3cd9a81SMatthew G. Knepley   if (snes->setfromoptionscalled) {ierr = SNESSetFromOptions(snes);CHKERRQ(ierr);}
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
11519b94acceSBarry Smith }
11529b94acceSBarry Smith 
1153bb9467b5SJed Brown /*@C
1154d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
1155d25893d9SBarry Smith    the nonlinear solvers.
1156d25893d9SBarry Smith 
1157d25893d9SBarry Smith    Logically Collective on SNES
1158d25893d9SBarry Smith 
1159d25893d9SBarry Smith    Input Parameters:
1160d25893d9SBarry Smith +  snes - the SNES context
1161d25893d9SBarry Smith .  compute - function to compute the context
1162d25893d9SBarry Smith -  destroy - function to destroy the context
1163d25893d9SBarry Smith 
1164d25893d9SBarry Smith    Level: intermediate
1165d25893d9SBarry Smith 
1166bb9467b5SJed Brown    Notes:
1167bb9467b5SJed Brown    This function is currently not available from Fortran.
1168bb9467b5SJed Brown 
1169d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
1170d25893d9SBarry Smith @*/
1171d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
1172d25893d9SBarry Smith {
1173d25893d9SBarry Smith   PetscFunctionBegin;
1174d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1175d25893d9SBarry Smith   snes->ops->usercompute = compute;
1176d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
1177d25893d9SBarry Smith   PetscFunctionReturn(0);
1178d25893d9SBarry Smith }
1179a847f771SSatish Balay 
1180b07ff414SBarry Smith /*@
11819b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
11829b94acceSBarry Smith    the nonlinear solvers.
11839b94acceSBarry Smith 
11843f9fe445SBarry Smith    Logically Collective on SNES
1185fee21e36SBarry Smith 
1186c7afd0dbSLois Curfman McInnes    Input Parameters:
1187c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1188c7afd0dbSLois Curfman McInnes -  usrP - optional user context
1189c7afd0dbSLois Curfman McInnes 
119036851e7fSLois Curfman McInnes    Level: intermediate
119136851e7fSLois Curfman McInnes 
119295452b02SPatrick Sanan    Fortran Notes:
119395452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1194daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1195daf670e6SBarry Smith 
1196ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
11979b94acceSBarry Smith @*/
11987087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
11999b94acceSBarry Smith {
12001b2093e4SBarry Smith   PetscErrorCode ierr;
1201b07ff414SBarry Smith   KSP            ksp;
12021b2093e4SBarry Smith 
12033a40ed3dSBarry Smith   PetscFunctionBegin;
12040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1205b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
1206b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
12079b94acceSBarry Smith   snes->user = usrP;
12083a40ed3dSBarry Smith   PetscFunctionReturn(0);
12099b94acceSBarry Smith }
121074679c65SBarry Smith 
1211b07ff414SBarry Smith /*@
12129b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
12139b94acceSBarry Smith    nonlinear solvers.
12149b94acceSBarry Smith 
1215c7afd0dbSLois Curfman McInnes    Not Collective
1216c7afd0dbSLois Curfman McInnes 
12179b94acceSBarry Smith    Input Parameter:
12189b94acceSBarry Smith .  snes - SNES context
12199b94acceSBarry Smith 
12209b94acceSBarry Smith    Output Parameter:
12219b94acceSBarry Smith .  usrP - user context
12229b94acceSBarry Smith 
122395452b02SPatrick Sanan    Fortran Notes:
122495452b02SPatrick Sanan     To use this from Fortran you must write a Fortran interface definition for this
1225daf670e6SBarry Smith     function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument.
1226daf670e6SBarry Smith 
122736851e7fSLois Curfman McInnes    Level: intermediate
122836851e7fSLois Curfman McInnes 
12299b94acceSBarry Smith .seealso: SNESSetApplicationContext()
12309b94acceSBarry Smith @*/
1231e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
12329b94acceSBarry Smith {
12333a40ed3dSBarry Smith   PetscFunctionBegin;
12340700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1235e71120c6SJed Brown   *(void**)usrP = snes->user;
12363a40ed3dSBarry Smith   PetscFunctionReturn(0);
12379b94acceSBarry Smith }
123874679c65SBarry Smith 
12399b94acceSBarry Smith /*@
1240ec5066bdSBarry Smith    SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian.
12413565c898SBarry Smith 
12423565c898SBarry Smith    Collective on SNES
12433565c898SBarry Smith 
12443565c898SBarry Smith    Input Parameters:
12453565c898SBarry Smith +  snes - SNES context
12464ddffce6SLisandro Dalcin .  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
12474ddffce6SLisandro 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
12483565c898SBarry Smith 
12493565c898SBarry Smith    Options Database:
12503565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
1251ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator
1252ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences.
1253ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow)
12543565c898SBarry Smith 
12553565c898SBarry Smith    Level: intermediate
12563565c898SBarry Smith 
1257ec5066bdSBarry Smith    Notes:
1258ec5066bdSBarry Smith       SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explictly with
1259ec5066bdSBarry Smith       finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object.
1260ec5066bdSBarry Smith 
1261ec5066bdSBarry Smith .seealso:   SNESGetUseMatrixFree(), MatCreateSNESMF(), SNESComputeJacobianDefaultColor()
12623565c898SBarry Smith @*/
12633565c898SBarry Smith PetscErrorCode  SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf)
12643565c898SBarry Smith {
12653565c898SBarry Smith   PetscFunctionBegin;
12663565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
126788b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf_operator,2);
126888b4c220SStefano Zampini   PetscValidLogicalCollectiveBool(snes,mf,3);
12694ddffce6SLisandro Dalcin   snes->mf          = mf_operator ? PETSC_TRUE : mf;
12703565c898SBarry Smith   snes->mf_operator = mf_operator;
12713565c898SBarry Smith   PetscFunctionReturn(0);
12723565c898SBarry Smith }
12733565c898SBarry Smith 
12743565c898SBarry Smith /*@
1275ec5066bdSBarry Smith    SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian.
12763565c898SBarry Smith 
12773565c898SBarry Smith    Collective on SNES
12783565c898SBarry Smith 
12793565c898SBarry Smith    Input Parameter:
12803565c898SBarry Smith .  snes - SNES context
12813565c898SBarry Smith 
12823565c898SBarry Smith    Output Parameters:
12834ddffce6SLisandro Dalcin +  mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used
12844ddffce6SLisandro 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
12853565c898SBarry Smith 
12863565c898SBarry Smith    Options Database:
12873565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator
12883565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator
12893565c898SBarry Smith 
12903565c898SBarry Smith    Level: intermediate
12913565c898SBarry Smith 
12923565c898SBarry Smith .seealso:   SNESSetUseMatrixFree(), MatCreateSNESMF()
12933565c898SBarry Smith @*/
12943565c898SBarry Smith PetscErrorCode  SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf)
12953565c898SBarry Smith {
12963565c898SBarry Smith   PetscFunctionBegin;
12973565c898SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12983565c898SBarry Smith   if (mf)          *mf          = snes->mf;
12993565c898SBarry Smith   if (mf_operator) *mf_operator = snes->mf_operator;
13003565c898SBarry Smith   PetscFunctionReturn(0);
13013565c898SBarry Smith }
13023565c898SBarry Smith 
13033565c898SBarry Smith /*@
1304c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1305c8228a4eSBarry Smith    at this time.
13069b94acceSBarry Smith 
1307c7afd0dbSLois Curfman McInnes    Not Collective
1308c7afd0dbSLois Curfman McInnes 
13099b94acceSBarry Smith    Input Parameter:
13109b94acceSBarry Smith .  snes - SNES context
13119b94acceSBarry Smith 
13129b94acceSBarry Smith    Output Parameter:
13139b94acceSBarry Smith .  iter - iteration number
13149b94acceSBarry Smith 
1315c8228a4eSBarry Smith    Notes:
1316c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1317c8228a4eSBarry Smith 
1318c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
131908405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
132008405cd6SLois Curfman McInnes .vb
132108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
132208405cd6SLois Curfman McInnes       if (!(it % 2)) {
132308405cd6SLois Curfman McInnes         [compute Jacobian here]
132408405cd6SLois Curfman McInnes       }
132508405cd6SLois Curfman McInnes .ve
1326c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
132708405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1328c8228a4eSBarry Smith 
1329c04deec6SBarry Smith    After the SNES solve is complete this will return the number of nonlinear iterations used.
1330c04deec6SBarry Smith 
133136851e7fSLois Curfman McInnes    Level: intermediate
133236851e7fSLois Curfman McInnes 
133371dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
13349b94acceSBarry Smith @*/
13357087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
13369b94acceSBarry Smith {
13373a40ed3dSBarry Smith   PetscFunctionBegin;
13380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13394482741eSBarry Smith   PetscValidIntPointer(iter,2);
13409b94acceSBarry Smith   *iter = snes->iter;
13413a40ed3dSBarry Smith   PetscFunctionReturn(0);
13429b94acceSBarry Smith }
134374679c65SBarry Smith 
1344360c497dSPeter Brune /*@
1345360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1346360c497dSPeter Brune 
1347360c497dSPeter Brune    Not Collective
1348360c497dSPeter Brune 
1349360c497dSPeter Brune    Input Parameter:
1350a2b725a8SWilliam Gropp +  snes - SNES context
1351a2b725a8SWilliam Gropp -  iter - iteration number
1352360c497dSPeter Brune 
1353360c497dSPeter Brune    Level: developer
1354360c497dSPeter Brune 
135571dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1356360c497dSPeter Brune @*/
1357360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1358360c497dSPeter Brune {
1359360c497dSPeter Brune   PetscErrorCode ierr;
1360360c497dSPeter Brune 
1361360c497dSPeter Brune   PetscFunctionBegin;
1362360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1363e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1364360c497dSPeter Brune   snes->iter = iter;
1365e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1366360c497dSPeter Brune   PetscFunctionReturn(0);
1367360c497dSPeter Brune }
1368360c497dSPeter Brune 
13699b94acceSBarry Smith /*@
1370b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
13719b94acceSBarry Smith    attempted by the nonlinear solver.
13729b94acceSBarry Smith 
1373c7afd0dbSLois Curfman McInnes    Not Collective
1374c7afd0dbSLois Curfman McInnes 
13759b94acceSBarry Smith    Input Parameter:
13769b94acceSBarry Smith .  snes - SNES context
13779b94acceSBarry Smith 
13789b94acceSBarry Smith    Output Parameter:
13799b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
13809b94acceSBarry Smith 
1381c96a6f78SLois Curfman McInnes    Notes:
1382c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1383c96a6f78SLois Curfman McInnes 
138436851e7fSLois Curfman McInnes    Level: intermediate
138536851e7fSLois Curfman McInnes 
1386e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
138758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
13889b94acceSBarry Smith @*/
13897087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
13909b94acceSBarry Smith {
13913a40ed3dSBarry Smith   PetscFunctionBegin;
13920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13934482741eSBarry Smith   PetscValidIntPointer(nfails,2);
139450ffb88aSMatthew Knepley   *nfails = snes->numFailures;
139550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
139650ffb88aSMatthew Knepley }
139750ffb88aSMatthew Knepley 
139850ffb88aSMatthew Knepley /*@
1399b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
140050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
140150ffb88aSMatthew Knepley 
140250ffb88aSMatthew Knepley    Not Collective
140350ffb88aSMatthew Knepley 
140450ffb88aSMatthew Knepley    Input Parameters:
140550ffb88aSMatthew Knepley +  snes     - SNES context
140650ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
140750ffb88aSMatthew Knepley 
140850ffb88aSMatthew Knepley    Level: intermediate
140950ffb88aSMatthew Knepley 
1410e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
141158ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
141250ffb88aSMatthew Knepley @*/
14137087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
141450ffb88aSMatthew Knepley {
141550ffb88aSMatthew Knepley   PetscFunctionBegin;
14160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
141750ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
141850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
141950ffb88aSMatthew Knepley }
142050ffb88aSMatthew Knepley 
142150ffb88aSMatthew Knepley /*@
1422b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
142350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
142450ffb88aSMatthew Knepley 
142550ffb88aSMatthew Knepley    Not Collective
142650ffb88aSMatthew Knepley 
142750ffb88aSMatthew Knepley    Input Parameter:
142850ffb88aSMatthew Knepley .  snes     - SNES context
142950ffb88aSMatthew Knepley 
143050ffb88aSMatthew Knepley    Output Parameter:
143150ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
143250ffb88aSMatthew Knepley 
143350ffb88aSMatthew Knepley    Level: intermediate
143450ffb88aSMatthew Knepley 
1435e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
143658ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
143758ebbce7SBarry Smith 
143850ffb88aSMatthew Knepley @*/
14397087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
144050ffb88aSMatthew Knepley {
144150ffb88aSMatthew Knepley   PetscFunctionBegin;
14420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14434482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
144450ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
14453a40ed3dSBarry Smith   PetscFunctionReturn(0);
14469b94acceSBarry Smith }
1447a847f771SSatish Balay 
14482541af92SBarry Smith /*@
14492541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
14502541af92SBarry Smith      done by SNES.
14512541af92SBarry Smith 
14522541af92SBarry Smith    Not Collective
14532541af92SBarry Smith 
14542541af92SBarry Smith    Input Parameter:
14552541af92SBarry Smith .  snes     - SNES context
14562541af92SBarry Smith 
14572541af92SBarry Smith    Output Parameter:
14582541af92SBarry Smith .  nfuncs - number of evaluations
14592541af92SBarry Smith 
14602541af92SBarry Smith    Level: intermediate
14612541af92SBarry Smith 
146295452b02SPatrick Sanan    Notes:
146395452b02SPatrick Sanan     Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1464971e163fSPeter Brune 
1465971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
14662541af92SBarry Smith @*/
14677087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
14682541af92SBarry Smith {
14692541af92SBarry Smith   PetscFunctionBegin;
14700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14712541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
14722541af92SBarry Smith   *nfuncs = snes->nfuncs;
14732541af92SBarry Smith   PetscFunctionReturn(0);
14742541af92SBarry Smith }
14752541af92SBarry Smith 
14763d4c4710SBarry Smith /*@
14773d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
14783d4c4710SBarry Smith    linear solvers.
14793d4c4710SBarry Smith 
14803d4c4710SBarry Smith    Not Collective
14813d4c4710SBarry Smith 
14823d4c4710SBarry Smith    Input Parameter:
14833d4c4710SBarry Smith .  snes - SNES context
14843d4c4710SBarry Smith 
14853d4c4710SBarry Smith    Output Parameter:
14863d4c4710SBarry Smith .  nfails - number of failed solves
14873d4c4710SBarry Smith 
14889d85da0cSMatthew G. Knepley    Level: intermediate
14899d85da0cSMatthew G. Knepley 
14909d85da0cSMatthew G. Knepley    Options Database Keys:
14919d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
14929d85da0cSMatthew G. Knepley 
14933d4c4710SBarry Smith    Notes:
14943d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
14953d4c4710SBarry Smith 
1496e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
14973d4c4710SBarry Smith @*/
14987087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
14993d4c4710SBarry Smith {
15003d4c4710SBarry Smith   PetscFunctionBegin;
15010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15023d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
15033d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
15043d4c4710SBarry Smith   PetscFunctionReturn(0);
15053d4c4710SBarry Smith }
15063d4c4710SBarry Smith 
15073d4c4710SBarry Smith /*@
15083d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
15093d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
15103d4c4710SBarry Smith 
15113f9fe445SBarry Smith    Logically Collective on SNES
15123d4c4710SBarry Smith 
15133d4c4710SBarry Smith    Input Parameters:
15143d4c4710SBarry Smith +  snes     - SNES context
15153d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
15163d4c4710SBarry Smith 
15173d4c4710SBarry Smith    Level: intermediate
15183d4c4710SBarry Smith 
15199d85da0cSMatthew G. Knepley    Options Database Keys:
15209d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated
15219d85da0cSMatthew G. Knepley 
152295452b02SPatrick Sanan    Notes:
152395452b02SPatrick Sanan     By default this is 0; that is SNES returns on the first failed linear solve
15243d4c4710SBarry Smith 
152558ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
15263d4c4710SBarry Smith @*/
15277087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
15283d4c4710SBarry Smith {
15293d4c4710SBarry Smith   PetscFunctionBegin;
15300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1531c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
15323d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
15333d4c4710SBarry Smith   PetscFunctionReturn(0);
15343d4c4710SBarry Smith }
15353d4c4710SBarry Smith 
15363d4c4710SBarry Smith /*@
15373d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
15383d4c4710SBarry Smith      are allowed before SNES terminates
15393d4c4710SBarry Smith 
15403d4c4710SBarry Smith    Not Collective
15413d4c4710SBarry Smith 
15423d4c4710SBarry Smith    Input Parameter:
15433d4c4710SBarry Smith .  snes     - SNES context
15443d4c4710SBarry Smith 
15453d4c4710SBarry Smith    Output Parameter:
15463d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
15473d4c4710SBarry Smith 
15483d4c4710SBarry Smith    Level: intermediate
15493d4c4710SBarry Smith 
155095452b02SPatrick Sanan    Notes:
155195452b02SPatrick Sanan     By default this is 1; that is SNES returns on the first failed linear solve
15523d4c4710SBarry Smith 
1553e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
15543d4c4710SBarry Smith @*/
15557087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
15563d4c4710SBarry Smith {
15573d4c4710SBarry Smith   PetscFunctionBegin;
15580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15593d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
15603d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
15613d4c4710SBarry Smith   PetscFunctionReturn(0);
15623d4c4710SBarry Smith }
15633d4c4710SBarry Smith 
1564c96a6f78SLois Curfman McInnes /*@
1565b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1566c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1567c96a6f78SLois Curfman McInnes 
1568c7afd0dbSLois Curfman McInnes    Not Collective
1569c7afd0dbSLois Curfman McInnes 
1570c96a6f78SLois Curfman McInnes    Input Parameter:
1571c96a6f78SLois Curfman McInnes .  snes - SNES context
1572c96a6f78SLois Curfman McInnes 
1573c96a6f78SLois Curfman McInnes    Output Parameter:
1574c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1575c96a6f78SLois Curfman McInnes 
1576c96a6f78SLois Curfman McInnes    Notes:
1577971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1578c96a6f78SLois Curfman McInnes 
1579010be392SBarry 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
1580010be392SBarry Smith    then call KSPGetIterationNumber() after the failed solve.
1581010be392SBarry Smith 
158236851e7fSLois Curfman McInnes    Level: intermediate
158336851e7fSLois Curfman McInnes 
158471dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1585c96a6f78SLois Curfman McInnes @*/
15867087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1587c96a6f78SLois Curfman McInnes {
15883a40ed3dSBarry Smith   PetscFunctionBegin;
15890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15904482741eSBarry Smith   PetscValidIntPointer(lits,2);
1591c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
15923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1593c96a6f78SLois Curfman McInnes }
1594c96a6f78SLois Curfman McInnes 
1595971e163fSPeter Brune /*@
1596971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1597971e163fSPeter Brune    are reset every time SNESSolve() is called.
1598971e163fSPeter Brune 
1599971e163fSPeter Brune    Logically Collective on SNES
1600971e163fSPeter Brune 
1601971e163fSPeter Brune    Input Parameter:
1602971e163fSPeter Brune +  snes - SNES context
1603971e163fSPeter Brune -  reset - whether to reset the counters or not
1604971e163fSPeter Brune 
1605971e163fSPeter Brune    Notes:
1606fa19ca70SBarry Smith    This defaults to PETSC_TRUE
1607971e163fSPeter Brune 
1608971e163fSPeter Brune    Level: developer
1609971e163fSPeter Brune 
1610734794cfSBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetLinearSolveIterations(), SNESGetNPC()
1611971e163fSPeter Brune @*/
1612971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1613971e163fSPeter Brune {
1614971e163fSPeter Brune   PetscFunctionBegin;
1615971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1616971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1617971e163fSPeter Brune   snes->counters_reset = reset;
1618971e163fSPeter Brune   PetscFunctionReturn(0);
1619971e163fSPeter Brune }
1620971e163fSPeter Brune 
162182bf6240SBarry Smith 
16222999313aSBarry Smith /*@
16232999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
16242999313aSBarry Smith 
16252999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
16262999313aSBarry Smith 
16272999313aSBarry Smith    Input Parameters:
16282999313aSBarry Smith +  snes - the SNES context
16292999313aSBarry Smith -  ksp - the KSP context
16302999313aSBarry Smith 
16312999313aSBarry Smith    Notes:
16322999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
16332999313aSBarry Smith    so this routine is rarely needed.
16342999313aSBarry Smith 
16352999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
16362999313aSBarry Smith    decreased by one.
16372999313aSBarry Smith 
16382999313aSBarry Smith    Level: developer
16392999313aSBarry Smith 
16402999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
16412999313aSBarry Smith @*/
16427087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
16432999313aSBarry Smith {
16442999313aSBarry Smith   PetscErrorCode ierr;
16452999313aSBarry Smith 
16462999313aSBarry Smith   PetscFunctionBegin;
16470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16480700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
16492999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
16507dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1651906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
16522999313aSBarry Smith   snes->ksp = ksp;
16532999313aSBarry Smith   PetscFunctionReturn(0);
16542999313aSBarry Smith }
16552999313aSBarry Smith 
16569b94acceSBarry Smith /* -----------------------------------------------------------*/
165752baeb72SSatish Balay /*@
16589b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
16599b94acceSBarry Smith 
1660d083f849SBarry Smith    Collective
1661c7afd0dbSLois Curfman McInnes 
1662c7afd0dbSLois Curfman McInnes    Input Parameters:
1663906ed7ccSBarry Smith .  comm - MPI communicator
16649b94acceSBarry Smith 
16659b94acceSBarry Smith    Output Parameter:
16669b94acceSBarry Smith .  outsnes - the new SNES context
16679b94acceSBarry Smith 
1668c7afd0dbSLois Curfman McInnes    Options Database Keys:
1669c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1670c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1671c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1672c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1673c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1674c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1675c1f60f51SBarry Smith 
167636851e7fSLois Curfman McInnes    Level: beginner
167736851e7fSLois Curfman McInnes 
167895452b02SPatrick Sanan    Developer Notes:
167995452b02SPatrick Sanan     SNES always creates a KSP object even though many SNES methods do not use it. This is
1680efd4aadfSBarry Smith                     unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the
1681efd4aadfSBarry Smith                     particular method does use KSP and regulates if the information about the KSP is printed
1682efd4aadfSBarry Smith                     in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused
1683efd4aadfSBarry Smith                     by help messages about meaningless SNES options.
1684efd4aadfSBarry Smith 
1685efd4aadfSBarry Smith                     SNES always creates the snes->kspconvctx even though it is used by only one type. This should
1686efd4aadfSBarry Smith                     be fixed.
1687efd4aadfSBarry Smith 
16883d5a8a6aSBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1689a8054027SBarry Smith 
16909b94acceSBarry Smith @*/
16917087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
16929b94acceSBarry Smith {
1693dfbe8321SBarry Smith   PetscErrorCode ierr;
16949b94acceSBarry Smith   SNES           snes;
1695fa9f3622SBarry Smith   SNESKSPEW      *kctx;
169637fcc0dbSBarry Smith 
16973a40ed3dSBarry Smith   PetscFunctionBegin;
1698ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
16990298fd71SBarry Smith   *outsnes = NULL;
1700607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
17018ba1e511SMatthew Knepley 
170273107ff1SLisandro Dalcin   ierr = PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
17037adad957SLisandro Dalcin 
17048d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
17052c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
170688976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
17079b94acceSBarry Smith   snes->max_its           = 50;
17089750a799SBarry Smith   snes->max_funcs         = 10000;
17099b94acceSBarry Smith   snes->norm              = 0.0;
1710c1e67a49SFande Kong   snes->xnorm             = 0.0;
1711c1e67a49SFande Kong   snes->ynorm             = 0.0;
1712365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
17136c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
17143a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17153a2046daSBarry Smith   snes->rtol              = 1.e-5;
17163a2046daSBarry Smith #else
1717b4874afaSBarry Smith   snes->rtol              = 1.e-8;
17183a2046daSBarry Smith #endif
1719b4874afaSBarry Smith   snes->ttol              = 0.0;
17203a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17213a2046daSBarry Smith   snes->abstol            = 1.e-25;
17223a2046daSBarry Smith #else
172370441072SBarry Smith   snes->abstol            = 1.e-50;
17243a2046daSBarry Smith #endif
17257cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE)
17267cd0ae37SLisandro Dalcin   snes->stol              = 1.e-5;
17277cd0ae37SLisandro Dalcin #else
1728c60f73f4SPeter Brune   snes->stol              = 1.e-8;
17297cd0ae37SLisandro Dalcin #endif
17303a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
17313a2046daSBarry Smith   snes->deltatol          = 1.e-6;
17323a2046daSBarry Smith #else
17334b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
17343a2046daSBarry Smith #endif
1735e37c518bSBarry Smith   snes->divtol            = 1.e4;
1736e37c518bSBarry Smith   snes->rnorm0            = 0;
17379b94acceSBarry Smith   snes->nfuncs            = 0;
173850ffb88aSMatthew Knepley   snes->numFailures       = 0;
173950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
17407a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1741e35cf81dSBarry Smith   snes->lagjacobian       = 1;
174237ec4e1aSPeter Brune   snes->jac_iter          = 0;
174337ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1744a8054027SBarry Smith   snes->lagpreconditioner = 1;
174537ec4e1aSPeter Brune   snes->pre_iter          = 0;
174637ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1747639f9d9dSBarry Smith   snes->numbermonitors    = 0;
17489e5d0892SLisandro Dalcin   snes->data              = NULL;
17494dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1750186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
17516f24a144SLois Curfman McInnes   snes->nwork             = 0;
17529e5d0892SLisandro Dalcin   snes->work              = NULL;
175358c9b817SLisandro Dalcin   snes->nvwork            = 0;
17549e5d0892SLisandro Dalcin   snes->vwork             = NULL;
1755758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1756758f92a0SBarry Smith   snes->conv_hist_max     = 0;
17570298fd71SBarry Smith   snes->conv_hist         = NULL;
17580298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1759758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1760971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1761e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1762184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1763efd4aadfSBarry Smith   snes->npcside           = PC_RIGHT;
1764b3cd9a81SMatthew G. Knepley   snes->setfromoptionscalled = 0;
1765c40d0f55SPeter Brune 
1766d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1767d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1768d8f46077SPeter Brune   snes->mf_version  = 1;
1769d8f46077SPeter Brune 
17703d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
17713d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
17723d4c4710SBarry Smith 
1773349187a7SBarry Smith   snes->vizerotolerance = 1.e-8;
177476bd3646SJed Brown   snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE;
1775349187a7SBarry Smith 
17764fc747eaSLawrence Mitchell   /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */
17774fc747eaSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
17784fc747eaSLawrence Mitchell 
17799b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1780b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1781f5af7f23SKarl Rupp 
17829b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
17839b94acceSBarry Smith   kctx->version     = 2;
17849b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
17859b94acceSBarry Smith                              this was too large for some test cases */
178675567043SBarry Smith   kctx->rtol_last   = 0.0;
17879b94acceSBarry Smith   kctx->rtol_max    = .9;
17889b94acceSBarry Smith   kctx->gamma       = 1.0;
178962d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
179071f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
17919b94acceSBarry Smith   kctx->threshold   = .1;
179275567043SBarry Smith   kctx->lresid_last = 0.0;
179375567043SBarry Smith   kctx->norm_last   = 0.0;
17949b94acceSBarry Smith 
17959b94acceSBarry Smith   *outsnes = snes;
17963a40ed3dSBarry Smith   PetscFunctionReturn(0);
17979b94acceSBarry Smith }
17989b94acceSBarry Smith 
179988f0584fSBarry Smith /*MC
1800411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
180188f0584fSBarry Smith 
180288f0584fSBarry Smith      Synopsis:
1803411c0326SBarry Smith      #include "petscsnes.h"
1804411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
180588f0584fSBarry Smith 
18061843f636SBarry Smith      Collective on snes
18071843f636SBarry Smith 
180888f0584fSBarry Smith      Input Parameters:
180988f0584fSBarry Smith +     snes - the SNES context
181088f0584fSBarry Smith .     x    - state at which to evaluate residual
181188f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
181288f0584fSBarry Smith 
181388f0584fSBarry Smith      Output Parameter:
181488f0584fSBarry Smith .     f  - vector to put residual (function value)
181588f0584fSBarry Smith 
1816878cb397SSatish Balay    Level: intermediate
1817878cb397SSatish Balay 
181888f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
181988f0584fSBarry Smith M*/
182088f0584fSBarry Smith 
18219b94acceSBarry Smith /*@C
18229b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
18239b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
18249b94acceSBarry Smith    equations.
18259b94acceSBarry Smith 
18263f9fe445SBarry Smith    Logically Collective on SNES
1827fee21e36SBarry Smith 
1828c7afd0dbSLois Curfman McInnes    Input Parameters:
1829c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1830c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1831f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1832c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
18330298fd71SBarry Smith          function evaluation routine (may be NULL)
18349b94acceSBarry Smith 
18359b94acceSBarry Smith    Notes:
18369b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
18379b94acceSBarry Smith $      f'(x) x = -f(x),
1838c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
18399b94acceSBarry Smith 
184036851e7fSLois Curfman McInnes    Level: beginner
184136851e7fSLois Curfman McInnes 
1842bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
18439b94acceSBarry Smith @*/
1844f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
18459b94acceSBarry Smith {
184685385478SLisandro Dalcin   PetscErrorCode ierr;
18476cab3a1bSJed Brown   DM             dm;
18486cab3a1bSJed Brown 
18493a40ed3dSBarry Smith   PetscFunctionBegin;
18500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1851d2a683ecSLisandro Dalcin   if (r) {
1852d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1853d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
185485385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
18556bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1856f5af7f23SKarl Rupp 
185785385478SLisandro Dalcin     snes->vec_func = r;
1858d2a683ecSLisandro Dalcin   }
18596cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1860f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
18613a40ed3dSBarry Smith   PetscFunctionReturn(0);
18629b94acceSBarry Smith }
18639b94acceSBarry Smith 
1864646217ecSPeter Brune 
1865e4ed7901SPeter Brune /*@C
1866e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1867e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1868e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1869e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1870e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1871e4ed7901SPeter Brune 
1872e4ed7901SPeter Brune    Logically Collective on SNES
1873e4ed7901SPeter Brune 
1874e4ed7901SPeter Brune    Input Parameters:
1875e4ed7901SPeter Brune +  snes - the SNES context
1876e4ed7901SPeter Brune -  f - vector to store function value
1877e4ed7901SPeter Brune 
1878e4ed7901SPeter Brune    Notes:
1879e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1880e4ed7901SPeter Brune 
1881e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1882e4ed7901SPeter Brune 
1883e4ed7901SPeter Brune    Level: developer
1884e4ed7901SPeter Brune 
1885e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1886e4ed7901SPeter Brune @*/
1887e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1888e4ed7901SPeter Brune {
1889e4ed7901SPeter Brune   PetscErrorCode ierr;
1890e4ed7901SPeter Brune   Vec            vec_func;
1891e4ed7901SPeter Brune 
1892e4ed7901SPeter Brune   PetscFunctionBegin;
1893e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1894e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1895e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1896efd4aadfSBarry Smith   if (snes->npcside== PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1897902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1898902f982fSPeter Brune     PetscFunctionReturn(0);
1899902f982fSPeter Brune   }
19000298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1901e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1902f5af7f23SKarl Rupp 
1903217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1904e4ed7901SPeter Brune   PetscFunctionReturn(0);
1905e4ed7901SPeter Brune }
1906e4ed7901SPeter Brune 
1907534ebe21SPeter Brune /*@
1908365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1909534ebe21SPeter Brune    of the SNES method.
1910534ebe21SPeter Brune 
1911534ebe21SPeter Brune    Logically Collective on SNES
1912534ebe21SPeter Brune 
1913534ebe21SPeter Brune    Input Parameters:
1914534ebe21SPeter Brune +  snes - the SNES context
1915365a6726SPeter Brune -  normschedule - the frequency of norm computation
1916534ebe21SPeter Brune 
1917517f1916SMatthew G. Knepley    Options Database Key:
1918517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1919517f1916SMatthew G. Knepley 
1920534ebe21SPeter Brune    Notes:
1921365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1922534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1923534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1924be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1925534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1926534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1927534ebe21SPeter Brune    their solution.
1928534ebe21SPeter Brune 
1929534ebe21SPeter Brune    Level: developer
1930534ebe21SPeter Brune 
1931365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1932534ebe21SPeter Brune @*/
1933365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1934534ebe21SPeter Brune {
1935534ebe21SPeter Brune   PetscFunctionBegin;
1936534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1937365a6726SPeter Brune   snes->normschedule = normschedule;
1938534ebe21SPeter Brune   PetscFunctionReturn(0);
1939534ebe21SPeter Brune }
1940534ebe21SPeter Brune 
1941534ebe21SPeter Brune 
1942534ebe21SPeter Brune /*@
1943365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1944534ebe21SPeter Brune    of the SNES method.
1945534ebe21SPeter Brune 
1946534ebe21SPeter Brune    Logically Collective on SNES
1947534ebe21SPeter Brune 
1948534ebe21SPeter Brune    Input Parameters:
1949534ebe21SPeter Brune +  snes - the SNES context
1950365a6726SPeter Brune -  normschedule - the type of the norm used
1951534ebe21SPeter Brune 
1952534ebe21SPeter Brune    Level: advanced
1953534ebe21SPeter Brune 
1954365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1955534ebe21SPeter Brune @*/
1956365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1957534ebe21SPeter Brune {
1958534ebe21SPeter Brune   PetscFunctionBegin;
1959534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1960365a6726SPeter Brune   *normschedule = snes->normschedule;
1961534ebe21SPeter Brune   PetscFunctionReturn(0);
1962534ebe21SPeter Brune }
1963534ebe21SPeter Brune 
196447073ea2SPeter Brune 
1965c5ce4427SMatthew G. Knepley /*@
1966c5ce4427SMatthew G. Knepley   SNESSetFunctionNorm - Sets the last computed residual norm.
1967c5ce4427SMatthew G. Knepley 
1968c5ce4427SMatthew G. Knepley   Logically Collective on SNES
1969c5ce4427SMatthew G. Knepley 
1970c5ce4427SMatthew G. Knepley   Input Parameters:
1971c5ce4427SMatthew G. Knepley + snes - the SNES context
1972c5ce4427SMatthew G. Knepley 
1973c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation
1974c5ce4427SMatthew G. Knepley 
1975c5ce4427SMatthew G. Knepley   Level: developer
1976c5ce4427SMatthew G. Knepley 
1977c5ce4427SMatthew G. Knepley .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1978c5ce4427SMatthew G. Knepley @*/
1979c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm)
1980c5ce4427SMatthew G. Knepley {
1981c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
1982c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1983c5ce4427SMatthew G. Knepley   snes->norm = norm;
1984c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
1985c5ce4427SMatthew G. Knepley }
1986c5ce4427SMatthew G. Knepley 
1987c5ce4427SMatthew G. Knepley /*@
1988c5ce4427SMatthew G. Knepley   SNESGetFunctionNorm - Gets the last computed norm of the residual
1989c5ce4427SMatthew G. Knepley 
1990c5ce4427SMatthew G. Knepley   Not Collective
1991c5ce4427SMatthew G. Knepley 
1992c5ce4427SMatthew G. Knepley   Input Parameter:
1993c5ce4427SMatthew G. Knepley . snes - the SNES context
1994c5ce4427SMatthew G. Knepley 
1995c5ce4427SMatthew G. Knepley   Output Parameter:
1996c5ce4427SMatthew G. Knepley . norm - the last computed residual norm
1997c5ce4427SMatthew G. Knepley 
1998c5ce4427SMatthew G. Knepley   Level: developer
1999c5ce4427SMatthew G. Knepley 
2000c5ce4427SMatthew G. Knepley .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
2001c5ce4427SMatthew G. Knepley @*/
2002c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm)
2003c5ce4427SMatthew G. Knepley {
2004c5ce4427SMatthew G. Knepley   PetscFunctionBegin;
2005c5ce4427SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2006c5ce4427SMatthew G. Knepley   PetscValidPointer(norm, 2);
2007c5ce4427SMatthew G. Knepley   *norm = snes->norm;
2008c5ce4427SMatthew G. Knepley   PetscFunctionReturn(0);
2009c5ce4427SMatthew G. Knepley }
2010c5ce4427SMatthew G. Knepley 
2011c1e67a49SFande Kong /*@
2012c1e67a49SFande Kong   SNESGetUpdateNorm - Gets the last computed norm of the Newton update
2013c1e67a49SFande Kong 
2014c1e67a49SFande Kong   Not Collective
2015c1e67a49SFande Kong 
2016c1e67a49SFande Kong   Input Parameter:
2017c1e67a49SFande Kong . snes - the SNES context
2018c1e67a49SFande Kong 
2019c1e67a49SFande Kong   Output Parameter:
2020c1e67a49SFande Kong . ynorm - the last computed update norm
2021c1e67a49SFande Kong 
2022c1e67a49SFande Kong   Level: developer
2023c1e67a49SFande Kong 
2024c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm()
2025c1e67a49SFande Kong @*/
2026c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm)
2027c1e67a49SFande Kong {
2028c1e67a49SFande Kong   PetscFunctionBegin;
2029c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2030c1e67a49SFande Kong   PetscValidPointer(ynorm, 2);
2031c1e67a49SFande Kong   *ynorm = snes->ynorm;
2032c1e67a49SFande Kong   PetscFunctionReturn(0);
2033c1e67a49SFande Kong }
2034c1e67a49SFande Kong 
2035c1e67a49SFande Kong /*@
20364591eaf2SFande Kong   SNESGetSolutionNorm - Gets the last computed norm of the solution
2037c1e67a49SFande Kong 
2038c1e67a49SFande Kong   Not Collective
2039c1e67a49SFande Kong 
2040c1e67a49SFande Kong   Input Parameter:
2041c1e67a49SFande Kong . snes - the SNES context
2042c1e67a49SFande Kong 
2043c1e67a49SFande Kong   Output Parameter:
2044c1e67a49SFande Kong . xnorm - the last computed solution norm
2045c1e67a49SFande Kong 
2046c1e67a49SFande Kong   Level: developer
2047c1e67a49SFande Kong 
2048c1e67a49SFande Kong .seealso: SNESSetNormSchedule(), SNESComputeFunction(), SNESGetFunctionNorm(), SNESGetUpdateNorm()
2049c1e67a49SFande Kong @*/
2050c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm)
2051c1e67a49SFande Kong {
2052c1e67a49SFande Kong   PetscFunctionBegin;
2053c1e67a49SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2054c1e67a49SFande Kong   PetscValidPointer(xnorm, 2);
2055c1e67a49SFande Kong   *xnorm = snes->xnorm;
2056c1e67a49SFande Kong   PetscFunctionReturn(0);
2057c1e67a49SFande Kong }
2058c1e67a49SFande Kong 
205947073ea2SPeter Brune /*@C
206047073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
206147073ea2SPeter Brune    of the SNES method.
206247073ea2SPeter Brune 
206347073ea2SPeter Brune    Logically Collective on SNES
206447073ea2SPeter Brune 
206547073ea2SPeter Brune    Input Parameters:
206647073ea2SPeter Brune +  snes - the SNES context
206747073ea2SPeter Brune -  normschedule - the frequency of norm computation
206847073ea2SPeter Brune 
206947073ea2SPeter Brune    Notes:
207047073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
207147073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
207247073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
2073be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
207447073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
207547073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
207647073ea2SPeter Brune    their solution.
207747073ea2SPeter Brune 
207847073ea2SPeter Brune    Level: developer
207947073ea2SPeter Brune 
208047073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
208147073ea2SPeter Brune @*/
208247073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
208347073ea2SPeter Brune {
208447073ea2SPeter Brune   PetscFunctionBegin;
208547073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
208647073ea2SPeter Brune   snes->functype = type;
208747073ea2SPeter Brune   PetscFunctionReturn(0);
208847073ea2SPeter Brune }
208947073ea2SPeter Brune 
209047073ea2SPeter Brune 
209147073ea2SPeter Brune /*@C
209247073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
209347073ea2SPeter Brune    of the SNES method.
209447073ea2SPeter Brune 
209547073ea2SPeter Brune    Logically Collective on SNES
209647073ea2SPeter Brune 
209747073ea2SPeter Brune    Input Parameters:
209847073ea2SPeter Brune +  snes - the SNES context
209947073ea2SPeter Brune -  normschedule - the type of the norm used
210047073ea2SPeter Brune 
210147073ea2SPeter Brune    Level: advanced
210247073ea2SPeter Brune 
210347073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
210447073ea2SPeter Brune @*/
210547073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
210647073ea2SPeter Brune {
210747073ea2SPeter Brune   PetscFunctionBegin;
210847073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
210947073ea2SPeter Brune   *type = snes->functype;
2110534ebe21SPeter Brune   PetscFunctionReturn(0);
2111534ebe21SPeter Brune }
2112534ebe21SPeter Brune 
2113bf388a1fSBarry Smith /*MC
2114be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
2115bf388a1fSBarry Smith 
2116bf388a1fSBarry Smith      Synopsis:
2117aaa7dc30SBarry Smith      #include <petscsnes.h>
2118be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
2119bf388a1fSBarry Smith 
21201843f636SBarry Smith      Collective on snes
21211843f636SBarry Smith 
21221843f636SBarry Smith      Input Parameters:
2123bf388a1fSBarry Smith +  X   - solution vector
2124bf388a1fSBarry Smith .  B   - RHS vector
2125bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
2126bf388a1fSBarry Smith 
21271843f636SBarry Smith      Output Parameter:
21281843f636SBarry Smith .  X   - solution vector
21291843f636SBarry Smith 
2130878cb397SSatish Balay    Level: intermediate
2131878cb397SSatish Balay 
2132be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
2133bf388a1fSBarry Smith M*/
2134bf388a1fSBarry Smith 
2135c79ef259SPeter Brune /*@C
2136be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
2137c79ef259SPeter Brune    use with composed nonlinear solvers.
2138c79ef259SPeter Brune 
2139c79ef259SPeter Brune    Input Parameters:
2140c79ef259SPeter Brune +  snes   - the SNES context
2141be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
2142c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
21430298fd71SBarry Smith             smoother evaluation routine (may be NULL)
2144c79ef259SPeter Brune 
2145c79ef259SPeter Brune    Notes:
2146be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
2147c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
2148c79ef259SPeter Brune 
2149d28543b3SPeter Brune    Level: intermediate
2150c79ef259SPeter Brune 
2151be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
2152c79ef259SPeter Brune @*/
2153be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
21546cab3a1bSJed Brown {
21556cab3a1bSJed Brown   PetscErrorCode ierr;
21566cab3a1bSJed Brown   DM             dm;
21576cab3a1bSJed Brown 
2158646217ecSPeter Brune   PetscFunctionBegin;
21596cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21606cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2161be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
2162646217ecSPeter Brune   PetscFunctionReturn(0);
2163646217ecSPeter Brune }
2164646217ecSPeter Brune 
216525acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
21668b0a5094SBarry Smith {
21678b0a5094SBarry Smith   PetscErrorCode ierr;
2168e03ab78fSPeter Brune   DM             dm;
2169942e3340SBarry Smith   DMSNES         sdm;
21706cab3a1bSJed Brown 
21718b0a5094SBarry Smith   PetscFunctionBegin;
2172e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2173942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
217425acbd8eSLisandro Dalcin   if (!sdm->ops->computepfunction) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
217525acbd8eSLisandro Dalcin   if (!sdm->ops->computepjacobian) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian.");
21768b0a5094SBarry Smith   /*  A(x)*x - b(x) */
217725acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user function");
217822c6f798SBarry Smith   ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
217925acbd8eSLisandro Dalcin   PetscStackPop;
218025acbd8eSLisandro Dalcin   PetscStackPush("SNES Picard user Jacobian");
2181d1e9a80fSBarry Smith   ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
218225acbd8eSLisandro Dalcin   PetscStackPop;
21838b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
218495eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
21858b0a5094SBarry Smith   PetscFunctionReturn(0);
21868b0a5094SBarry Smith }
21878b0a5094SBarry Smith 
218825acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
21898b0a5094SBarry Smith {
21908b0a5094SBarry Smith   PetscFunctionBegin;
2191e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
21928b0a5094SBarry Smith   PetscFunctionReturn(0);
21938b0a5094SBarry Smith }
21948b0a5094SBarry Smith 
21958b0a5094SBarry Smith /*@C
21960d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
21978b0a5094SBarry Smith 
21988b0a5094SBarry Smith    Logically Collective on SNES
21998b0a5094SBarry Smith 
22008b0a5094SBarry Smith    Input Parameters:
22018b0a5094SBarry Smith +  snes - the SNES context
22028b0a5094SBarry Smith .  r - vector to store function value
2203f8b49ee9SBarry Smith .  b - function evaluation routine
2204e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
2205e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
2206411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
22078b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
22080298fd71SBarry Smith          function evaluation routine (may be NULL)
22098b0a5094SBarry Smith 
22108b0a5094SBarry Smith    Notes:
2211f450aa47SBarry 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
2212f450aa47SBarry 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.
2213f450aa47SBarry Smith 
22148b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
22158b0a5094SBarry Smith 
22168b0a5094SBarry 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}
22178b0a5094SBarry 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.
22188b0a5094SBarry Smith 
22198b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
22208b0a5094SBarry Smith 
22210d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
22220d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
22238b0a5094SBarry Smith 
22248b0a5094SBarry 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
22258b0a5094SBarry 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
22268b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
22278b0a5094SBarry Smith 
2228f450aa47SBarry Smith    Level: intermediate
22298b0a5094SBarry Smith 
2230411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
22318b0a5094SBarry Smith @*/
2232d1e9a80fSBarry 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)
22338b0a5094SBarry Smith {
22348b0a5094SBarry Smith   PetscErrorCode ierr;
2235e03ab78fSPeter Brune   DM             dm;
2236e03ab78fSPeter Brune 
22378b0a5094SBarry Smith   PetscFunctionBegin;
22388b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2239e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
2240f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
22418b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
2242e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
22438b0a5094SBarry Smith   PetscFunctionReturn(0);
22448b0a5094SBarry Smith }
22458b0a5094SBarry Smith 
22467971a8bfSPeter Brune /*@C
22477971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
22487971a8bfSPeter Brune 
22497971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
22507971a8bfSPeter Brune 
22517971a8bfSPeter Brune    Input Parameter:
22527971a8bfSPeter Brune .  snes - the SNES context
22537971a8bfSPeter Brune 
22547971a8bfSPeter Brune    Output Parameter:
22550298fd71SBarry Smith +  r - the function (or NULL)
2256f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
2257e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
2258e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
2259f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
22600298fd71SBarry Smith -  ctx - the function context (or NULL)
22617971a8bfSPeter Brune 
22627971a8bfSPeter Brune    Level: advanced
22637971a8bfSPeter Brune 
2264e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
22657971a8bfSPeter Brune @*/
2266d1e9a80fSBarry 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)
22677971a8bfSPeter Brune {
22687971a8bfSPeter Brune   PetscErrorCode ierr;
22697971a8bfSPeter Brune   DM             dm;
22707971a8bfSPeter Brune 
22717971a8bfSPeter Brune   PetscFunctionBegin;
22727971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22730298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
2274e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
22757971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2276f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
22777971a8bfSPeter Brune   PetscFunctionReturn(0);
22787971a8bfSPeter Brune }
22797971a8bfSPeter Brune 
2280d25893d9SBarry Smith /*@C
2281d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
2282d25893d9SBarry Smith 
2283d25893d9SBarry Smith    Logically Collective on SNES
2284d25893d9SBarry Smith 
2285d25893d9SBarry Smith    Input Parameters:
2286d25893d9SBarry Smith +  snes - the SNES context
2287d25893d9SBarry Smith .  func - function evaluation routine
2288d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
22890298fd71SBarry Smith          function evaluation routine (may be NULL)
2290d25893d9SBarry Smith 
2291d25893d9SBarry Smith    Calling sequence of func:
2292d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
2293d25893d9SBarry Smith 
2294d25893d9SBarry Smith .  f - function vector
2295d25893d9SBarry Smith -  ctx - optional user-defined function context
2296d25893d9SBarry Smith 
2297d25893d9SBarry Smith    Level: intermediate
2298d25893d9SBarry Smith 
2299d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
2300d25893d9SBarry Smith @*/
2301d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
2302d25893d9SBarry Smith {
2303d25893d9SBarry Smith   PetscFunctionBegin;
2304d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2305d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
2306d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
2307d25893d9SBarry Smith   PetscFunctionReturn(0);
2308d25893d9SBarry Smith }
2309d25893d9SBarry Smith 
23103ab0aad5SBarry Smith /* --------------------------------------------------------------- */
23111096aae1SMatthew Knepley /*@C
23121096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
23131096aae1SMatthew Knepley    it assumes a zero right hand side.
23141096aae1SMatthew Knepley 
23153f9fe445SBarry Smith    Logically Collective on SNES
23161096aae1SMatthew Knepley 
23171096aae1SMatthew Knepley    Input Parameter:
23181096aae1SMatthew Knepley .  snes - the SNES context
23191096aae1SMatthew Knepley 
23201096aae1SMatthew Knepley    Output Parameter:
23210298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
23221096aae1SMatthew Knepley 
23231096aae1SMatthew Knepley    Level: intermediate
23241096aae1SMatthew Knepley 
232585385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
23261096aae1SMatthew Knepley @*/
23277087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
23281096aae1SMatthew Knepley {
23291096aae1SMatthew Knepley   PetscFunctionBegin;
23300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23311096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
233285385478SLisandro Dalcin   *rhs = snes->vec_rhs;
23331096aae1SMatthew Knepley   PetscFunctionReturn(0);
23341096aae1SMatthew Knepley }
23351096aae1SMatthew Knepley 
23369b94acceSBarry Smith /*@
2337bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
23389b94acceSBarry Smith 
2339c7afd0dbSLois Curfman McInnes    Collective on SNES
2340c7afd0dbSLois Curfman McInnes 
23419b94acceSBarry Smith    Input Parameters:
2342c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2343c7afd0dbSLois Curfman McInnes -  x - input vector
23449b94acceSBarry Smith 
23459b94acceSBarry Smith    Output Parameter:
23463638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
23479b94acceSBarry Smith 
23481bffabb2SLois Curfman McInnes    Notes:
234936851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
235036851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
235136851e7fSLois Curfman McInnes    themselves.
235236851e7fSLois Curfman McInnes 
235336851e7fSLois Curfman McInnes    Level: developer
235436851e7fSLois Curfman McInnes 
2355a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
23569b94acceSBarry Smith @*/
23577087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
23589b94acceSBarry Smith {
2359dfbe8321SBarry Smith   PetscErrorCode ierr;
23606cab3a1bSJed Brown   DM             dm;
2361942e3340SBarry Smith   DMSNES         sdm;
23629b94acceSBarry Smith 
23633a40ed3dSBarry Smith   PetscFunctionBegin;
23640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23650700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
23660700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2367c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2368c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
236962796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2370184914b5SBarry Smith 
23716cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2372942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
237332f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
237494db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2375ccf3c845SPeter Brune       ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
237694db00ebSBarry Smith     }
23778860a134SJunchao Zhang     ierr = VecLockReadPush(x);CHKERRQ(ierr);
2378d64ed03dSBarry Smith     PetscStackPush("SNES user function");
23798ddeebeaSSteve Benbow     /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */
23808ddeebeaSSteve Benbow     snes->domainerror = PETSC_FALSE;
238122c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2382d64ed03dSBarry Smith     PetscStackPop;
23838860a134SJunchao Zhang     ierr = VecLockReadPop(x);CHKERRQ(ierr);
238494db00ebSBarry Smith     if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) {
2385ccf3c845SPeter Brune       ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
238694db00ebSBarry Smith     }
2387c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2388c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2389644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
239085385478SLisandro Dalcin   if (snes->vec_rhs) {
239185385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
23923ab0aad5SBarry Smith   }
2393ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2394422a814eSBarry Smith   /*
2395422a814eSBarry Smith      domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will
2396422a814eSBarry Smith      propagate the value to all processes
2397422a814eSBarry Smith   */
2398422a814eSBarry Smith   if (snes->domainerror) {
2399422a814eSBarry Smith     ierr = VecSetInf(y);CHKERRQ(ierr);
2400422a814eSBarry Smith   }
24013a40ed3dSBarry Smith   PetscFunctionReturn(0);
24029b94acceSBarry Smith }
24039b94acceSBarry Smith 
2404c79ef259SPeter Brune /*@
2405be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2406c79ef259SPeter Brune 
2407c79ef259SPeter Brune    Collective on SNES
2408c79ef259SPeter Brune 
2409c79ef259SPeter Brune    Input Parameters:
2410c79ef259SPeter Brune +  snes - the SNES context
2411c79ef259SPeter Brune .  x - input vector
2412c79ef259SPeter Brune -  b - rhs vector
2413c79ef259SPeter Brune 
2414c79ef259SPeter Brune    Output Parameter:
2415c79ef259SPeter Brune .  x - new solution vector
2416c79ef259SPeter Brune 
2417c79ef259SPeter Brune    Notes:
2418be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2419c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2420c79ef259SPeter Brune    themselves.
2421c79ef259SPeter Brune 
2422c79ef259SPeter Brune    Level: developer
2423c79ef259SPeter Brune 
2424be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2425c79ef259SPeter Brune @*/
2426be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2427646217ecSPeter Brune {
2428646217ecSPeter Brune   PetscErrorCode ierr;
24296cab3a1bSJed Brown   DM             dm;
2430942e3340SBarry Smith   DMSNES         sdm;
2431646217ecSPeter Brune 
2432646217ecSPeter Brune   PetscFunctionBegin;
2433646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2434646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2435646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2436646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2437646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
243862796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2439be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
24406cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2441942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
244222c6f798SBarry Smith   if (sdm->ops->computegs) {
24438860a134SJunchao Zhang     if (b) {ierr = VecLockReadPush(b);CHKERRQ(ierr);}
2444be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
244522c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2446646217ecSPeter Brune     PetscStackPop;
24478860a134SJunchao Zhang     if (b) {ierr = VecLockReadPop(b);CHKERRQ(ierr);}
2448be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2449be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
2450646217ecSPeter Brune   PetscFunctionReturn(0);
2451646217ecSPeter Brune }
2452646217ecSPeter Brune 
2453e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes)
2454e885f1abSBarry Smith {
245512837594SBarry Smith   Mat               A,B,C,D,jacobian;
2456e885f1abSBarry Smith   Vec               x = snes->vec_sol,f = snes->vec_func;
2457e885f1abSBarry Smith   PetscErrorCode    ierr;
2458e885f1abSBarry Smith   PetscReal         nrm,gnorm;
245981e7118cSBarry Smith   PetscReal         threshold = 1.e-5;
24600e276705SLisandro Dalcin   MatType           mattype;
2461e885f1abSBarry Smith   PetscInt          m,n,M,N;
2462e885f1abSBarry Smith   void              *functx;
24632cd624f9SStefano Zampini   PetscBool         complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose;
24643325ff46SBarry Smith   PetscViewer       viewer,mviewer;
2465e885f1abSBarry Smith   MPI_Comm          comm;
2466e885f1abSBarry Smith   PetscInt          tabs;
246712837594SBarry Smith   static PetscBool  directionsprinted = PETSC_FALSE;
24683325ff46SBarry Smith   PetscViewerFormat format;
2469e885f1abSBarry Smith 
2470e885f1abSBarry Smith   PetscFunctionBegin;
2471fc35ed60SBarry Smith   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
247212837594SBarry Smith   ierr = PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test);CHKERRQ(ierr);
247312837594SBarry Smith   ierr = PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL);CHKERRQ(ierr);
24743325ff46SBarry 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);
247518d89885SKarl Rupp   if (!complete_print) {
2476455a5933SJed Brown     ierr = PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL);CHKERRQ(ierr);
247718d89885SKarl Rupp     ierr = PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print);CHKERRQ(ierr);
247818d89885SKarl Rupp   }
247918d89885SKarl Rupp   /* for compatibility with PETSc 3.9 and older. */
2480455a5933SJed 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);
248118d89885SKarl 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);
2482e885f1abSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
2483e885f1abSBarry Smith   if (!test) PetscFunctionReturn(0);
2484e885f1abSBarry Smith 
2485e885f1abSBarry Smith   ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2486e885f1abSBarry Smith   ierr = PetscViewerASCIIGetStdout(comm,&viewer);CHKERRQ(ierr);
2487e885f1abSBarry Smith   ierr = PetscViewerASCIIGetTab(viewer, &tabs);CHKERRQ(ierr);
2488e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel);CHKERRQ(ierr);
248912837594SBarry Smith   ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian -------------\n");CHKERRQ(ierr);
249012837594SBarry Smith   if (!complete_print && !directionsprinted) {
249112837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n");CHKERRQ(ierr);
2492fc35ed60SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    of hand-coded and finite difference Jacobian entries greater than <threshold>.\n");CHKERRQ(ierr);
249312837594SBarry Smith   }
249412837594SBarry Smith   if (!directionsprinted) {
249512837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n");CHKERRQ(ierr);
2496e885f1abSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    O(1.e-8), the hand-coded Jacobian is probably correct.\n");CHKERRQ(ierr);
249712837594SBarry Smith     directionsprinted = PETSC_TRUE;
2498e885f1abSBarry Smith   }
24993325ff46SBarry Smith   if (complete_print) {
25003325ff46SBarry Smith     ierr = PetscViewerPushFormat(mviewer,format);CHKERRQ(ierr);
2501e885f1abSBarry Smith   }
2502e885f1abSBarry Smith 
250312837594SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg);CHKERRQ(ierr);
250412837594SBarry Smith   if (!flg) jacobian = snes->jacobian;
250512837594SBarry Smith   else jacobian = snes->jacobian_pre;
250612837594SBarry Smith 
2507a82339d0SMatthew G. Knepley   if (!x) {
2508a82339d0SMatthew G. Knepley     ierr = MatCreateVecs(jacobian, &x, NULL);CHKERRQ(ierr);
2509a82339d0SMatthew G. Knepley   } else {
2510a82339d0SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) x);CHKERRQ(ierr);
2511a82339d0SMatthew G. Knepley   }
2512a82339d0SMatthew G. Knepley   if (!f) {
2513a82339d0SMatthew G. Knepley     ierr = VecDuplicate(x, &f);CHKERRQ(ierr);
2514a82339d0SMatthew G. Knepley   } else {
2515a82339d0SMatthew G. Knepley     ierr = PetscObjectReference((PetscObject) f);CHKERRQ(ierr);
2516a82339d0SMatthew G. Knepley   }
2517a82339d0SMatthew G. Knepley   /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */
2518a82339d0SMatthew G. Knepley   ierr = SNESComputeFunction(snes,x,f);CHKERRQ(ierr);
2519a82339d0SMatthew G. Knepley   ierr = VecDestroy(&f);CHKERRQ(ierr);
25202cd624f9SStefano Zampini   ierr = PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose);CHKERRQ(ierr);
252112837594SBarry Smith   while (jacobian) {
25222cd624f9SStefano Zampini     Mat JT = NULL, Jsave = NULL;
25232cd624f9SStefano Zampini 
25242cd624f9SStefano Zampini     if (istranspose) {
25252cd624f9SStefano Zampini       ierr = MatCreateTranspose(jacobian,&JT);CHKERRQ(ierr);
25262cd624f9SStefano Zampini       Jsave = jacobian;
25272cd624f9SStefano Zampini       jacobian = JT;
25282cd624f9SStefano Zampini     }
25290e276705SLisandro Dalcin     ierr = PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"");CHKERRQ(ierr);
253012837594SBarry Smith     if (flg) {
253112837594SBarry Smith       A    = jacobian;
253212837594SBarry Smith       ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
253312837594SBarry Smith     } else {
25340bacdadaSStefano Zampini       ierr = MatComputeOperator(jacobian,MATAIJ,&A);CHKERRQ(ierr);
253512837594SBarry Smith     }
2536e885f1abSBarry Smith 
25370e276705SLisandro Dalcin     ierr = MatGetType(A,&mattype);CHKERRQ(ierr);
2538e885f1abSBarry Smith     ierr = MatGetSize(A,&M,&N);CHKERRQ(ierr);
2539e885f1abSBarry Smith     ierr = MatGetLocalSize(A,&m,&n);CHKERRQ(ierr);
25400e276705SLisandro Dalcin     ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr);
25410e276705SLisandro Dalcin     ierr = MatSetType(B,mattype);CHKERRQ(ierr);
2542e885f1abSBarry Smith     ierr = MatSetSizes(B,m,n,M,N);CHKERRQ(ierr);
25430e276705SLisandro Dalcin     ierr = MatSetBlockSizesFromMats(B,A,A);CHKERRQ(ierr);
2544e885f1abSBarry Smith     ierr = MatSetUp(B);CHKERRQ(ierr);
2545e885f1abSBarry Smith     ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
2546e885f1abSBarry Smith 
2547e885f1abSBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
2548e885f1abSBarry Smith     ierr = SNESComputeJacobianDefault(snes,x,B,B,functx);CHKERRQ(ierr);
254912837594SBarry Smith 
255012837594SBarry Smith     ierr = MatDuplicate(B,MAT_COPY_VALUES,&D);CHKERRQ(ierr);
255112837594SBarry Smith     ierr = MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
255212837594SBarry Smith     ierr = MatNorm(D,NORM_FROBENIUS,&nrm);CHKERRQ(ierr);
2553e885f1abSBarry Smith     ierr = MatNorm(A,NORM_FROBENIUS,&gnorm);CHKERRQ(ierr);
255412837594SBarry Smith     ierr = MatDestroy(&D);CHKERRQ(ierr);
255512837594SBarry Smith     if (!gnorm) gnorm = 1; /* just in case */
255612837594SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm);CHKERRQ(ierr);
255712837594SBarry Smith 
2558e885f1abSBarry Smith     if (complete_print) {
255912837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded Jacobian ----------\n");CHKERRQ(ierr);
25601878987eSStefano Zampini       ierr = MatView(A,mviewer);CHKERRQ(ierr);
256112837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Finite difference Jacobian ----------\n");CHKERRQ(ierr);
25623325ff46SBarry Smith       ierr = MatView(B,mviewer);CHKERRQ(ierr);
2563e885f1abSBarry Smith     }
2564e885f1abSBarry Smith 
2565df10fb39SFande Kong     if (threshold_print || complete_print) {
2566e885f1abSBarry Smith       PetscInt          Istart, Iend, *ccols, bncols, cncols, j, row;
2567e885f1abSBarry Smith       PetscScalar       *cvals;
2568e885f1abSBarry Smith       const PetscInt    *bcols;
2569e885f1abSBarry Smith       const PetscScalar *bvals;
2570e885f1abSBarry Smith 
2571e885f1abSBarry Smith       ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr);
25720e276705SLisandro Dalcin       ierr = MatSetType(C,mattype);CHKERRQ(ierr);
2573e885f1abSBarry Smith       ierr = MatSetSizes(C,m,n,M,N);CHKERRQ(ierr);
25740e276705SLisandro Dalcin       ierr = MatSetBlockSizesFromMats(C,A,A);CHKERRQ(ierr);
2575e885f1abSBarry Smith       ierr = MatSetUp(C);CHKERRQ(ierr);
2576e885f1abSBarry Smith       ierr = MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
25770e276705SLisandro Dalcin 
25780e276705SLisandro Dalcin       ierr = MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
2579e885f1abSBarry Smith       ierr = MatGetOwnershipRange(B,&Istart,&Iend);CHKERRQ(ierr);
2580e885f1abSBarry Smith 
2581e885f1abSBarry Smith       for (row = Istart; row < Iend; row++) {
2582e885f1abSBarry Smith         ierr = MatGetRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2583e885f1abSBarry Smith         ierr = PetscMalloc2(bncols,&ccols,bncols,&cvals);CHKERRQ(ierr);
2584e885f1abSBarry Smith         for (j = 0, cncols = 0; j < bncols; j++) {
258523a52b1dSBarry Smith           if (PetscAbsScalar(bvals[j]) > threshold) {
2586e885f1abSBarry Smith             ccols[cncols] = bcols[j];
2587e885f1abSBarry Smith             cvals[cncols] = bvals[j];
2588e885f1abSBarry Smith             cncols += 1;
2589e885f1abSBarry Smith           }
2590e885f1abSBarry Smith         }
2591e885f1abSBarry Smith         if (cncols) {
2592e885f1abSBarry Smith           ierr = MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES);CHKERRQ(ierr);
2593e885f1abSBarry Smith         }
2594e885f1abSBarry Smith         ierr = MatRestoreRow(B,row,&bncols,&bcols,&bvals);CHKERRQ(ierr);
2595e885f1abSBarry Smith         ierr = PetscFree2(ccols,cvals);CHKERRQ(ierr);
2596e885f1abSBarry Smith       }
2597e885f1abSBarry Smith       ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2598e885f1abSBarry Smith       ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
259912837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold);CHKERRQ(ierr);
260018d89885SKarl Rupp       ierr = MatView(C,complete_print ? mviewer : viewer);CHKERRQ(ierr);
2601e885f1abSBarry Smith       ierr = MatDestroy(&C);CHKERRQ(ierr);
2602e885f1abSBarry Smith     }
260312837594SBarry Smith     ierr = MatDestroy(&A);CHKERRQ(ierr);
2604e885f1abSBarry Smith     ierr = MatDestroy(&B);CHKERRQ(ierr);
26052cd624f9SStefano Zampini     ierr = MatDestroy(&JT);CHKERRQ(ierr);
26062cd624f9SStefano Zampini     if (Jsave) jacobian = Jsave;
260712837594SBarry Smith     if (jacobian != snes->jacobian_pre) {
260812837594SBarry Smith       jacobian = snes->jacobian_pre;
260912837594SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  ---------- Testing Jacobian for preconditioner -------------\n");CHKERRQ(ierr);
261012837594SBarry Smith     }
261112837594SBarry Smith     else jacobian = NULL;
261212837594SBarry Smith   }
2613a82339d0SMatthew G. Knepley   ierr = VecDestroy(&x);CHKERRQ(ierr);
26143325ff46SBarry Smith   if (complete_print) {
26153325ff46SBarry Smith     ierr = PetscViewerPopFormat(mviewer);CHKERRQ(ierr);
26163325ff46SBarry Smith   }
2617a0c90127SFande Kong   if (mviewer) { ierr = PetscViewerDestroy(&mviewer);CHKERRQ(ierr); }
2618e885f1abSBarry Smith   ierr = PetscViewerASCIISetTab(viewer,tabs);CHKERRQ(ierr);
2619e885f1abSBarry Smith   PetscFunctionReturn(0);
2620e885f1abSBarry Smith }
2621e885f1abSBarry Smith 
262262fef451SLois Curfman McInnes /*@
2623bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
262462fef451SLois Curfman McInnes 
2625d083f849SBarry Smith    Collective on SNES
2626c7afd0dbSLois Curfman McInnes 
262762fef451SLois Curfman McInnes    Input Parameters:
2628c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2629c7afd0dbSLois Curfman McInnes -  x - input vector
263062fef451SLois Curfman McInnes 
263162fef451SLois Curfman McInnes    Output Parameters:
2632c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2633d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2634fee21e36SBarry Smith 
2635e35cf81dSBarry Smith   Options Database Keys:
2636e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2637693365a8SJed Brown .    -snes_lag_jacobian <lag>
2638455a5933SJed 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.
2639455a5933SJed 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
2640693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2641693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2642693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
26434c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
264494d6a431SBarry Smith .    -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference
2645c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2646c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2647c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2648c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
26494c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2650c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2651c01495d3SJed Brown 
2652e35cf81dSBarry Smith 
265362fef451SLois Curfman McInnes    Notes:
265462fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
265562fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
265662fef451SLois Curfman McInnes 
265795452b02SPatrick Sanan    Developer Notes:
265895452b02SPatrick 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
2659e885f1abSBarry Smith       for with the SNESType of test that has been removed.
2660e885f1abSBarry Smith 
266136851e7fSLois Curfman McInnes    Level: developer
266236851e7fSLois Curfman McInnes 
2663e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
266462fef451SLois Curfman McInnes @*/
2665d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
26669b94acceSBarry Smith {
2667dfbe8321SBarry Smith   PetscErrorCode ierr;
2668ace3abfcSBarry Smith   PetscBool      flag;
26696cab3a1bSJed Brown   DM             dm;
2670942e3340SBarry Smith   DMSNES         sdm;
2671e0e3a89bSBarry Smith   KSP            ksp;
26723a40ed3dSBarry Smith 
26733a40ed3dSBarry Smith   PetscFunctionBegin;
26740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
26750700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2676c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
267762796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
26786cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2679942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
26803232da50SPeter Brune 
2681ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2682ebd3b9afSBarry Smith 
2683ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2684ebd3b9afSBarry Smith 
2685fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2686fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2687f5af7f23SKarl Rupp 
2688fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2689fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2690e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
269194ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2692ebd3b9afSBarry Smith     if (flag) {
269394ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
269494ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2695ebd3b9afSBarry Smith     }
2696e35cf81dSBarry Smith     PetscFunctionReturn(0);
269737ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2698e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
269994ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2700ebd3b9afSBarry Smith     if (flag) {
270194ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
270294ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2703ebd3b9afSBarry Smith     }
2704e35cf81dSBarry Smith     PetscFunctionReturn(0);
2705e35cf81dSBarry Smith   }
2706efd4aadfSBarry Smith   if (snes->npc && snes->npcside== PC_LEFT) {
270794ab13aaSBarry Smith     ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
270894ab13aaSBarry Smith     ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2709d728fb7dSPeter Brune     PetscFunctionReturn(0);
2710d728fb7dSPeter Brune   }
2711e35cf81dSBarry Smith 
271294ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
27138860a134SJunchao Zhang   ierr = VecLockReadPush(X);CHKERRQ(ierr);
2714d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2715d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2716d64ed03dSBarry Smith   PetscStackPop;
27178860a134SJunchao Zhang   ierr = VecLockReadPop(X);CHKERRQ(ierr);
271894ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
271928d58a37SPierre Jolivet 
272028d58a37SPierre Jolivet   /* attach latest linearization point to the preconditioning matrix */
272128d58a37SPierre Jolivet   ierr = PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X);CHKERRQ(ierr);
2722a8054027SBarry Smith 
2723e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2724e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
27253b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
27263b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2727d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
27283b4f5425SBarry Smith     snes->lagpreconditioner = -1;
27293b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2730a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2731d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
273237ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2733a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2734d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2735d1e9a80fSBarry Smith   } else {
2736d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2737d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2738a8054027SBarry Smith   }
2739a8054027SBarry Smith 
2740e885f1abSBarry Smith   ierr = SNESTestJacobian(snes);CHKERRQ(ierr);
27416d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
274294ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
274394ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2744693365a8SJed Brown   {
2745693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
274616413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag);CHKERRQ(ierr);
274716413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
274816413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
274916413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator);CHKERRQ(ierr);
2750693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
27510298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2752693365a8SJed Brown       PetscViewer  vdraw,vstdout;
27536b3a5b13SJed Brown       PetscBool    flg;
2754693365a8SJed Brown       if (flag_operator) {
27550bacdadaSStefano Zampini         ierr = MatComputeOperator(A,MATAIJ,&Bexp_mine);CHKERRQ(ierr);
2756693365a8SJed Brown         Bexp = Bexp_mine;
2757693365a8SJed Brown       } else {
2758693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2759b9e7e5c1SBarry Smith         ierr = PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
276094ab13aaSBarry Smith         if (flg) Bexp = B;
2761693365a8SJed Brown         else {
2762693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
27630bacdadaSStefano Zampini           ierr = MatComputeOperator(B,MATAIJ,&Bexp_mine);CHKERRQ(ierr);
2764693365a8SJed Brown           Bexp = Bexp_mine;
2765693365a8SJed Brown         }
2766693365a8SJed Brown       }
2767693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2768d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2769ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2770693365a8SJed Brown       if (flag_draw || flag_contour) {
27719e5d0892SLisandro Dalcin         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2772693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
27730298fd71SBarry Smith       } else vdraw = NULL;
2774693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2775693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2776693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2777693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2778693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2779693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2780693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2781693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2782693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2783693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2784693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2785693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2786693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2787693365a8SJed Brown       }
2788693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2789693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2790693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2791693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2792693365a8SJed Brown     }
2793693365a8SJed Brown   }
27944c30e9fbSJed Brown   {
27956719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
27966719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
279716413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag);CHKERRQ(ierr);
279816413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display);CHKERRQ(ierr);
279916413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw);CHKERRQ(ierr);
280016413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour);CHKERRQ(ierr);
280116413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold);CHKERRQ(ierr);
280227b0f280SBarry Smith     if (flag_threshold) {
2803c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
2804c5929fdfSBarry Smith       ierr = PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
280527b0f280SBarry Smith     }
28066719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
28074c30e9fbSJed Brown       Mat            Bfd;
28084c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2809335efc43SPeter Brune       MatColoring    coloring;
28104c30e9fbSJed Brown       ISColoring     iscoloring;
28114c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
28124c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
28134c30e9fbSJed Brown       void           *funcctx;
28146719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
28154c30e9fbSJed Brown 
281694ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2817335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2818335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2819335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2820335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2821335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
28224c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2823f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2824f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
28254c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
28264c30e9fbSJed Brown 
28274c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
28280298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
28294c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
28304c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
28314c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
28324c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2833d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
28344c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
28354c30e9fbSJed Brown 
2836ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
28374c30e9fbSJed Brown       if (flag_draw || flag_contour) {
28389e5d0892SLisandro Dalcin         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
28394c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
28400298fd71SBarry Smith       } else vdraw = NULL;
28414c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
284294ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
284394ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
28444c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
28456719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
28464c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
284794ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
28484c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
28496719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
28504c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
285157622a8eSBarry 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);
28526719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
28534c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
28544c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
28554c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
28564c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
28574c30e9fbSJed Brown       }
28584c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
28596719d8e4SJed Brown 
28606719d8e4SJed Brown       if (flag_threshold) {
28616719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
286294ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
286394ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
28646719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
28656719d8e4SJed Brown           const PetscScalar *ba,*ca;
28666719d8e4SJed Brown           const PetscInt    *bj,*cj;
28676719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
28686719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
286994ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
28706719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
287194ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
28726719d8e4SJed Brown           for (j=0; j<bn; j++) {
28736719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
28746719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
28756719d8e4SJed Brown               maxentrycol = bj[j];
28766719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
28776719d8e4SJed Brown             }
28786719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
28796719d8e4SJed Brown               maxdiffcol = bj[j];
28806719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
28816719d8e4SJed Brown             }
28826719d8e4SJed Brown             if (rdiff > maxrdiff) {
28836719d8e4SJed Brown               maxrdiffcol = bj[j];
28846719d8e4SJed Brown               maxrdiff    = rdiff;
28856719d8e4SJed Brown             }
28866719d8e4SJed Brown           }
28876719d8e4SJed Brown           if (maxrdiff > 1) {
288857622a8eSBarry 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);
28896719d8e4SJed Brown             for (j=0; j<bn; j++) {
28906719d8e4SJed Brown               PetscReal rdiff;
28916719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
28926719d8e4SJed Brown               if (rdiff > 1) {
289357622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
28946719d8e4SJed Brown               }
28956719d8e4SJed Brown             }
28966719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
28976719d8e4SJed Brown           }
289894ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
28996719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
29006719d8e4SJed Brown         }
29016719d8e4SJed Brown       }
29024c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
29034c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
29044c30e9fbSJed Brown     }
29054c30e9fbSJed Brown   }
29063a40ed3dSBarry Smith   PetscFunctionReturn(0);
29079b94acceSBarry Smith }
29089b94acceSBarry Smith 
2909bf388a1fSBarry Smith /*MC
2910411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2911bf388a1fSBarry Smith 
2912bf388a1fSBarry Smith      Synopsis:
2913411c0326SBarry Smith      #include "petscsnes.h"
2914411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2915bf388a1fSBarry Smith 
29161843f636SBarry Smith      Collective on snes
29171843f636SBarry Smith 
29181843f636SBarry Smith     Input Parameters:
29191843f636SBarry Smith +  x - input vector, the Jacobian is to be computed at this value
2920bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2921bf388a1fSBarry Smith 
29221843f636SBarry Smith     Output Parameters:
29231843f636SBarry Smith +  Amat - the matrix that defines the (approximate) Jacobian
29241843f636SBarry Smith -  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
29251843f636SBarry Smith 
2926878cb397SSatish Balay    Level: intermediate
2927878cb397SSatish Balay 
2928bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2929bf388a1fSBarry Smith M*/
2930bf388a1fSBarry Smith 
29319b94acceSBarry Smith /*@C
29329b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2933044dda88SLois Curfman McInnes    location to store the matrix.
29349b94acceSBarry Smith 
2935d083f849SBarry Smith    Logically Collective on SNES
2936c7afd0dbSLois Curfman McInnes 
29379b94acceSBarry Smith    Input Parameters:
2938c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2939e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2940e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2941411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2942c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
29430298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
29449b94acceSBarry Smith 
29459b94acceSBarry Smith    Notes:
2946e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
294716913363SBarry Smith    each matrix.
294816913363SBarry Smith 
2949895c21f2SBarry Smith    If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null
2950895c21f2SBarry Smith    space to Amat and the KSP solvers will automatically use that null space as needed during the solution process.
2951895c21f2SBarry Smith 
29528d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2953a8a26c1eSJed Brown    must be a MatFDColoring.
2954a8a26c1eSJed Brown 
2955c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2956c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2957c3cc8fd1SJed Brown 
295836851e7fSLois Curfman McInnes    Level: beginner
295936851e7fSLois Curfman McInnes 
2960411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2961411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
29629b94acceSBarry Smith @*/
2963d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
29649b94acceSBarry Smith {
2965dfbe8321SBarry Smith   PetscErrorCode ierr;
29666cab3a1bSJed Brown   DM             dm;
29673a7fca6bSBarry Smith 
29683a40ed3dSBarry Smith   PetscFunctionBegin;
29690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2970e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2971e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2972e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2973e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
29746cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2975f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2976e5d3d808SBarry Smith   if (Amat) {
2977e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
29786bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2979f5af7f23SKarl Rupp 
2980e5d3d808SBarry Smith     snes->jacobian = Amat;
29813a7fca6bSBarry Smith   }
2982e5d3d808SBarry Smith   if (Pmat) {
2983e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
29846bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2985f5af7f23SKarl Rupp 
2986e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
29873a7fca6bSBarry Smith   }
29883a40ed3dSBarry Smith   PetscFunctionReturn(0);
29899b94acceSBarry Smith }
299062fef451SLois Curfman McInnes 
2991c2aafc4cSSatish Balay /*@C
2992b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2993b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2994b4fd4287SBarry Smith 
2995c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2996c7afd0dbSLois Curfman McInnes 
2997b4fd4287SBarry Smith    Input Parameter:
2998b4fd4287SBarry Smith .  snes - the nonlinear solver context
2999b4fd4287SBarry Smith 
3000b4fd4287SBarry Smith    Output Parameters:
3001e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
3002e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
3003411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
30040298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
3005fee21e36SBarry Smith 
300636851e7fSLois Curfman McInnes    Level: advanced
300736851e7fSLois Curfman McInnes 
3008411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
3009b4fd4287SBarry Smith @*/
3010d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
3011b4fd4287SBarry Smith {
30126cab3a1bSJed Brown   PetscErrorCode ierr;
30136cab3a1bSJed Brown   DM             dm;
3014942e3340SBarry Smith   DMSNES         sdm;
30156cab3a1bSJed Brown 
30163a40ed3dSBarry Smith   PetscFunctionBegin;
30170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3018e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
3019e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
30206cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3021942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
3022f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
30236cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
30243a40ed3dSBarry Smith   PetscFunctionReturn(0);
3025b4fd4287SBarry Smith }
3026b4fd4287SBarry Smith 
302758b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes)
302858b371f3SBarry Smith {
302958b371f3SBarry Smith   PetscErrorCode ierr;
303058b371f3SBarry Smith   DM             dm;
303158b371f3SBarry Smith   DMSNES         sdm;
303258b371f3SBarry Smith 
303358b371f3SBarry Smith   PetscFunctionBegin;
303458b371f3SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
303558b371f3SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
303658b371f3SBarry Smith   if (!sdm->ops->computejacobian && snes->jacobian_pre) {
303758b371f3SBarry Smith     DM        dm;
303858b371f3SBarry Smith     PetscBool isdense,ismf;
303958b371f3SBarry Smith 
304058b371f3SBarry Smith     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
304158b371f3SBarry Smith     ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL);CHKERRQ(ierr);
304258b371f3SBarry Smith     ierr = PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL);CHKERRQ(ierr);
304358b371f3SBarry Smith     if (isdense) {
304458b371f3SBarry Smith       ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL);CHKERRQ(ierr);
304558b371f3SBarry Smith     } else if (!ismf) {
304658b371f3SBarry Smith       ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
304758b371f3SBarry Smith     }
304858b371f3SBarry Smith   }
304958b371f3SBarry Smith   PetscFunctionReturn(0);
305058b371f3SBarry Smith }
305158b371f3SBarry Smith 
30529b94acceSBarry Smith /*@
30539b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
3054272ac6f2SLois Curfman McInnes    of a nonlinear solver.
30559b94acceSBarry Smith 
3056fee21e36SBarry Smith    Collective on SNES
3057fee21e36SBarry Smith 
3058c7afd0dbSLois Curfman McInnes    Input Parameters:
305970e92668SMatthew Knepley .  snes - the SNES context
3060c7afd0dbSLois Curfman McInnes 
3061272ac6f2SLois Curfman McInnes    Notes:
3062272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
3063272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
3064272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
3065272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
3066272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
3067272ac6f2SLois Curfman McInnes 
306836851e7fSLois Curfman McInnes    Level: advanced
306936851e7fSLois Curfman McInnes 
30709b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
30719b94acceSBarry Smith @*/
30727087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
30739b94acceSBarry Smith {
3074dfbe8321SBarry Smith   PetscErrorCode ierr;
30756cab3a1bSJed Brown   DM             dm;
3076942e3340SBarry Smith   DMSNES         sdm;
3077c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
30786e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
30796b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
30806b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
30816e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
30826e2a1849SPeter Brune   Vec            f,fpc;
30836e2a1849SPeter Brune   void           *funcctx;
3084d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
30851eb13d49SPeter Brune   void           *jacctx,*appctx;
308632b97717SPeter Brune   Mat            j,jpre;
30873a40ed3dSBarry Smith 
30883a40ed3dSBarry Smith   PetscFunctionBegin;
30890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30904dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
3091e3ed9ee7SBarry Smith   ierr = PetscLogEventBegin(SNES_Setup,snes,0,0,0);CHKERRQ(ierr);
30929b94acceSBarry Smith 
30937adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
309404d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
309585385478SLisandro Dalcin   }
309685385478SLisandro Dalcin 
30970298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
309858c9b817SLisandro Dalcin 
30996cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3100942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
3101ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
310258b371f3SBarry Smith   ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr);
310358b371f3SBarry Smith 
31046cab3a1bSJed Brown   if (!snes->vec_func) {
31056cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
3106214df951SJed Brown   }
3107efd51863SBarry Smith 
310822d28d08SBarry Smith   if (!snes->ksp) {
310922d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
311022d28d08SBarry Smith   }
3111b710008aSBarry Smith 
3112d8d34be6SBarry Smith   if (snes->linesearch) {
31137601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
3114ed07d7d7SPeter Brune     ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
3115d8d34be6SBarry Smith   }
31169e764e56SPeter Brune 
3117efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
3118172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
3119172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
3120172a4300SPeter Brune   }
3121d8f46077SPeter Brune 
3122efd4aadfSBarry Smith   if (snes->npc) {
31236e2a1849SPeter Brune     /* copy the DM over */
31246e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3125efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc,dm);CHKERRQ(ierr);
31266e2a1849SPeter Brune 
31276e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
31286e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
3129efd4aadfSBarry Smith     ierr = SNESSetFunction(snes->npc,fpc,func,funcctx);CHKERRQ(ierr);
313032b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
3131efd4aadfSBarry Smith     ierr = SNESSetJacobian(snes->npc,j,jpre,jac,jacctx);CHKERRQ(ierr);
31321eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
3133efd4aadfSBarry Smith     ierr = SNESSetApplicationContext(snes->npc,appctx);CHKERRQ(ierr);
31346e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
31356e2a1849SPeter Brune 
31366e2a1849SPeter Brune     /* copy the function pointers over */
3137efd4aadfSBarry Smith     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
31386e2a1849SPeter Brune 
31396e2a1849SPeter Brune     /* default to 1 iteration */
3140efd4aadfSBarry Smith     ierr = SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs);CHKERRQ(ierr);
3141efd4aadfSBarry Smith     if (snes->npcside==PC_RIGHT) {
3142efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
3143a9936a0cSPeter Brune     } else {
3144efd4aadfSBarry Smith       ierr = SNESSetNormSchedule(snes->npc,SNES_NORM_NONE);CHKERRQ(ierr);
3145a9936a0cSPeter Brune     }
3146efd4aadfSBarry Smith     ierr = SNESSetFromOptions(snes->npc);CHKERRQ(ierr);
31476e2a1849SPeter Brune 
31486e2a1849SPeter Brune     /* copy the line search context over */
3149d8d34be6SBarry Smith     if (snes->linesearch && snes->npc->linesearch) {
31507601faf0SJed Brown       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
3151efd4aadfSBarry Smith       ierr = SNESGetLineSearch(snes->npc,&pclinesearch);CHKERRQ(ierr);
31526b2b7091SBarry Smith       ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
31536b2b7091SBarry Smith       ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
31546b2b7091SBarry Smith       ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
31556b2b7091SBarry Smith       ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
31566e2a1849SPeter Brune       ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
31576e2a1849SPeter Brune     }
3158d8d34be6SBarry Smith   }
315932b97717SPeter Brune   if (snes->mf) {
316032b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
316132b97717SPeter Brune   }
316232b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
316332b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
316432b97717SPeter Brune   }
31656e2a1849SPeter Brune 
316637ec4e1aSPeter Brune   snes->jac_iter = 0;
316737ec4e1aSPeter Brune   snes->pre_iter = 0;
316837ec4e1aSPeter Brune 
3169410397dcSLisandro Dalcin   if (snes->ops->setup) {
3170410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
3171410397dcSLisandro Dalcin   }
317258c9b817SLisandro Dalcin 
317358b371f3SBarry Smith   ierr = SNESSetDefaultComputeJacobian(snes);CHKERRQ(ierr);
317458b371f3SBarry Smith 
3175efd4aadfSBarry Smith   if (snes->npc && (snes->npcside== PC_LEFT)) {
31766c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
3177d8d34be6SBarry Smith       if (snes->linesearch){
317855d4788fSPeter Brune         ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
3179be95d8f1SBarry Smith         ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
31806c67d002SPeter Brune       }
31816c67d002SPeter Brune     }
3182d8d34be6SBarry Smith   }
3183e3ed9ee7SBarry Smith   ierr = PetscLogEventEnd(SNES_Setup,snes,0,0,0);CHKERRQ(ierr);
31847aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
31853a40ed3dSBarry Smith   PetscFunctionReturn(0);
31869b94acceSBarry Smith }
31879b94acceSBarry Smith 
318837596af1SLisandro Dalcin /*@
318937596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
319037596af1SLisandro Dalcin 
319137596af1SLisandro Dalcin    Collective on SNES
319237596af1SLisandro Dalcin 
319337596af1SLisandro Dalcin    Input Parameter:
319437596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
319537596af1SLisandro Dalcin 
3196d25893d9SBarry Smith    Level: intermediate
3197d25893d9SBarry Smith 
319895452b02SPatrick Sanan    Notes:
319995452b02SPatrick Sanan     Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
320037596af1SLisandro Dalcin 
320137596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
320237596af1SLisandro Dalcin @*/
320337596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
320437596af1SLisandro Dalcin {
320537596af1SLisandro Dalcin   PetscErrorCode ierr;
320637596af1SLisandro Dalcin 
320737596af1SLisandro Dalcin   PetscFunctionBegin;
320837596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3209d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
3210d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
32110298fd71SBarry Smith     snes->user = NULL;
3212d25893d9SBarry Smith   }
3213efd4aadfSBarry Smith   if (snes->npc) {
3214efd4aadfSBarry Smith     ierr = SNESReset(snes->npc);CHKERRQ(ierr);
32158a23116dSBarry Smith   }
32168a23116dSBarry Smith 
321737596af1SLisandro Dalcin   if (snes->ops->reset) {
321837596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
321937596af1SLisandro Dalcin   }
32209e764e56SPeter Brune   if (snes->ksp) {
32219e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
32229e764e56SPeter Brune   }
32239e764e56SPeter Brune 
32249e764e56SPeter Brune   if (snes->linesearch) {
3225f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
32269e764e56SPeter Brune   }
32279e764e56SPeter Brune 
32286bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
32296bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
32306bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
32316bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
32326bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
32336bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
3234c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
3235c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
3236f5af7f23SKarl Rupp 
323740fdac6aSLawrence Mitchell   snes->alwayscomputesfinalresidual = PETSC_FALSE;
323840fdac6aSLawrence Mitchell 
323937596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
324037596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
324137596af1SLisandro Dalcin   PetscFunctionReturn(0);
324237596af1SLisandro Dalcin }
324337596af1SLisandro Dalcin 
324452baeb72SSatish Balay /*@
32459b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
32469b94acceSBarry Smith    with SNESCreate().
32479b94acceSBarry Smith 
3248c7afd0dbSLois Curfman McInnes    Collective on SNES
3249c7afd0dbSLois Curfman McInnes 
32509b94acceSBarry Smith    Input Parameter:
32519b94acceSBarry Smith .  snes - the SNES context
32529b94acceSBarry Smith 
325336851e7fSLois Curfman McInnes    Level: beginner
325436851e7fSLois Curfman McInnes 
325563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
32569b94acceSBarry Smith @*/
32576bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
32589b94acceSBarry Smith {
32596849ba73SBarry Smith   PetscErrorCode ierr;
32603a40ed3dSBarry Smith 
32613a40ed3dSBarry Smith   PetscFunctionBegin;
32626bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
32636bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
32649e5d0892SLisandro Dalcin   if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);}
3265d4bb536fSBarry Smith 
32666bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
3267efd4aadfSBarry Smith   ierr = SNESDestroy(&(*snes)->npc);CHKERRQ(ierr);
32686b8b9a38SLisandro Dalcin 
3269e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
3270e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
32716bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
32726d4c513bSLisandro Dalcin 
327333124788SMatthew G. Knepley   if ((*snes)->dm) {ierr = DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes);CHKERRQ(ierr);}
32746bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
32756bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
3276f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
32776b8b9a38SLisandro Dalcin 
32786bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
32796bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
32806bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
32816b8b9a38SLisandro Dalcin   }
3282071fcb05SBarry Smith   if ((*snes)->conv_hist_alloc) {
3283071fcb05SBarry Smith     ierr = PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its);CHKERRQ(ierr);
328458c9b817SLisandro Dalcin   }
32856bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
3286a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
32873a40ed3dSBarry Smith   PetscFunctionReturn(0);
32889b94acceSBarry Smith }
32899b94acceSBarry Smith 
32909b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
32919b94acceSBarry Smith 
3292a8054027SBarry Smith /*@
3293a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
3294a8054027SBarry Smith 
32953f9fe445SBarry Smith    Logically Collective on SNES
3296a8054027SBarry Smith 
3297a8054027SBarry Smith    Input Parameters:
3298a8054027SBarry Smith +  snes - the SNES context
3299a8054027SBarry 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
33003b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3301a8054027SBarry Smith 
3302a8054027SBarry Smith    Options Database Keys:
33033d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
33043d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
33053d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
33063d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3307a8054027SBarry Smith 
3308a8054027SBarry Smith    Notes:
3309a8054027SBarry Smith    The default is 1
33103d5a8a6aSBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called
3311a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
3312a8054027SBarry Smith 
3313a8054027SBarry Smith    Level: intermediate
3314a8054027SBarry Smith 
33153d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetLagPreconditionerPersists(),
33163d5a8a6aSBarry Smith           SNESSetLagJacobianPersists()
3317a8054027SBarry Smith 
3318a8054027SBarry Smith @*/
33197087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
3320a8054027SBarry Smith {
3321a8054027SBarry Smith   PetscFunctionBegin;
33220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3323e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3324e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3325c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3326a8054027SBarry Smith   snes->lagpreconditioner = lag;
3327a8054027SBarry Smith   PetscFunctionReturn(0);
3328a8054027SBarry Smith }
3329a8054027SBarry Smith 
3330efd51863SBarry Smith /*@
3331efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
3332efd51863SBarry Smith 
3333efd51863SBarry Smith    Logically Collective on SNES
3334efd51863SBarry Smith 
3335efd51863SBarry Smith    Input Parameters:
3336efd51863SBarry Smith +  snes - the SNES context
3337efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
3338efd51863SBarry Smith 
3339efd51863SBarry Smith    Options Database Keys:
3340efd51863SBarry Smith .    -snes_grid_sequence <steps>
3341efd51863SBarry Smith 
3342efd51863SBarry Smith    Level: intermediate
3343efd51863SBarry Smith 
3344c0df2a02SJed Brown    Notes:
3345c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3346c0df2a02SJed Brown 
3347fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetGridSequence()
3348efd51863SBarry Smith 
3349efd51863SBarry Smith @*/
3350efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
3351efd51863SBarry Smith {
3352efd51863SBarry Smith   PetscFunctionBegin;
3353efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3354efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
3355efd51863SBarry Smith   snes->gridsequence = steps;
3356efd51863SBarry Smith   PetscFunctionReturn(0);
3357efd51863SBarry Smith }
3358efd51863SBarry Smith 
3359fa19ca70SBarry Smith /*@
3360fa19ca70SBarry Smith    SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does
3361fa19ca70SBarry Smith 
3362fa19ca70SBarry Smith    Logically Collective on SNES
3363fa19ca70SBarry Smith 
3364fa19ca70SBarry Smith    Input Parameter:
3365fa19ca70SBarry Smith .  snes - the SNES context
3366fa19ca70SBarry Smith 
3367fa19ca70SBarry Smith    Output Parameter:
3368fa19ca70SBarry Smith .  steps - the number of refinements to do, defaults to 0
3369fa19ca70SBarry Smith 
3370fa19ca70SBarry Smith    Options Database Keys:
3371fa19ca70SBarry Smith .    -snes_grid_sequence <steps>
3372fa19ca70SBarry Smith 
3373fa19ca70SBarry Smith    Level: intermediate
3374fa19ca70SBarry Smith 
3375fa19ca70SBarry Smith    Notes:
3376fa19ca70SBarry Smith    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
3377fa19ca70SBarry Smith 
3378fa19ca70SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESSetGridSequence()
3379fa19ca70SBarry Smith 
3380fa19ca70SBarry Smith @*/
3381fa19ca70SBarry Smith PetscErrorCode  SNESGetGridSequence(SNES snes,PetscInt *steps)
3382fa19ca70SBarry Smith {
3383fa19ca70SBarry Smith   PetscFunctionBegin;
3384fa19ca70SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3385fa19ca70SBarry Smith   *steps = snes->gridsequence;
3386fa19ca70SBarry Smith   PetscFunctionReturn(0);
3387fa19ca70SBarry Smith }
3388fa19ca70SBarry Smith 
3389a8054027SBarry Smith /*@
3390a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
3391a8054027SBarry Smith 
33923f9fe445SBarry Smith    Not Collective
3393a8054027SBarry Smith 
3394a8054027SBarry Smith    Input Parameter:
3395a8054027SBarry Smith .  snes - the SNES context
3396a8054027SBarry Smith 
3397a8054027SBarry Smith    Output Parameter:
3398a8054027SBarry Smith .   lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
33993b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
3400a8054027SBarry Smith 
3401a8054027SBarry Smith    Options Database Keys:
34023d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34033d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34043d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34053d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
3406a8054027SBarry Smith 
3407a8054027SBarry Smith    Notes:
3408a8054027SBarry Smith    The default is 1
3409a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3410a8054027SBarry Smith 
3411a8054027SBarry Smith    Level: intermediate
3412a8054027SBarry Smith 
34133d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3414a8054027SBarry Smith 
3415a8054027SBarry Smith @*/
34167087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
3417a8054027SBarry Smith {
3418a8054027SBarry Smith   PetscFunctionBegin;
34190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3420a8054027SBarry Smith   *lag = snes->lagpreconditioner;
3421a8054027SBarry Smith   PetscFunctionReturn(0);
3422a8054027SBarry Smith }
3423a8054027SBarry Smith 
3424e35cf81dSBarry Smith /*@
3425e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
3426e35cf81dSBarry Smith      often the preconditioner is rebuilt.
3427e35cf81dSBarry Smith 
34283f9fe445SBarry Smith    Logically Collective on SNES
3429e35cf81dSBarry Smith 
3430e35cf81dSBarry Smith    Input Parameters:
3431e35cf81dSBarry Smith +  snes - the SNES context
3432e35cf81dSBarry 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
3433fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
3434e35cf81dSBarry Smith 
3435e35cf81dSBarry Smith    Options Database Keys:
34363d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
34373d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
34383d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
34393d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag.
3440e35cf81dSBarry Smith 
3441e35cf81dSBarry Smith    Notes:
3442e35cf81dSBarry Smith    The default is 1
3443e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
3444fe3ffe1eSBarry 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
3445fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
3446e35cf81dSBarry Smith 
3447e35cf81dSBarry Smith    Level: intermediate
3448e35cf81dSBarry Smith 
34493d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3450e35cf81dSBarry Smith 
3451e35cf81dSBarry Smith @*/
34527087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
3453e35cf81dSBarry Smith {
3454e35cf81dSBarry Smith   PetscFunctionBegin;
34550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3456e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
3457e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
3458c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
3459e35cf81dSBarry Smith   snes->lagjacobian = lag;
3460e35cf81dSBarry Smith   PetscFunctionReturn(0);
3461e35cf81dSBarry Smith }
3462e35cf81dSBarry Smith 
3463e35cf81dSBarry Smith /*@
3464e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
3465e35cf81dSBarry Smith 
34663f9fe445SBarry Smith    Not Collective
3467e35cf81dSBarry Smith 
3468e35cf81dSBarry Smith    Input Parameter:
3469e35cf81dSBarry Smith .  snes - the SNES context
3470e35cf81dSBarry Smith 
3471e35cf81dSBarry Smith    Output Parameter:
3472e35cf81dSBarry 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
3473e35cf81dSBarry Smith          the Jacobian is built etc.
3474e35cf81dSBarry Smith 
3475e35cf81dSBarry Smith    Notes:
3476e35cf81dSBarry Smith    The default is 1
34773d5a8a6aSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called.
3478e35cf81dSBarry Smith 
3479e35cf81dSBarry Smith    Level: intermediate
3480e35cf81dSBarry Smith 
34813d5a8a6aSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner(), SNESSetLagJacobianPersists(), SNESSetLagPreconditionerPersists()
3482e35cf81dSBarry Smith 
3483e35cf81dSBarry Smith @*/
34847087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
3485e35cf81dSBarry Smith {
3486e35cf81dSBarry Smith   PetscFunctionBegin;
34870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3488e35cf81dSBarry Smith   *lag = snes->lagjacobian;
3489e35cf81dSBarry Smith   PetscFunctionReturn(0);
3490e35cf81dSBarry Smith }
3491e35cf81dSBarry Smith 
349237ec4e1aSPeter Brune /*@
349337ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
349437ec4e1aSPeter Brune 
349537ec4e1aSPeter Brune    Logically collective on SNES
349637ec4e1aSPeter Brune 
349737ec4e1aSPeter Brune    Input Parameter:
349837ec4e1aSPeter Brune +  snes - the SNES context
34999d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
350037ec4e1aSPeter Brune 
350137ec4e1aSPeter Brune    Options Database Keys:
35023d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35033d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35043d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35053d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
35063d5a8a6aSBarry Smith 
350737ec4e1aSPeter Brune 
350895452b02SPatrick Sanan    Notes:
350995452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
351037ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
351137ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
351237ec4e1aSPeter Brune 
351337ec4e1aSPeter Brune    Level: developer
351437ec4e1aSPeter Brune 
35153d5a8a6aSBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagJacobianPersists()
351637ec4e1aSPeter Brune 
351737ec4e1aSPeter Brune @*/
351837ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
351937ec4e1aSPeter Brune {
352037ec4e1aSPeter Brune   PetscFunctionBegin;
352137ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
352237ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
352337ec4e1aSPeter Brune   snes->lagjac_persist = flg;
352437ec4e1aSPeter Brune   PetscFunctionReturn(0);
352537ec4e1aSPeter Brune }
352637ec4e1aSPeter Brune 
352737ec4e1aSPeter Brune /*@
352837ec4e1aSPeter Brune    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
352937ec4e1aSPeter Brune 
353037ec4e1aSPeter Brune    Logically Collective on SNES
353137ec4e1aSPeter Brune 
353237ec4e1aSPeter Brune    Input Parameter:
353337ec4e1aSPeter Brune +  snes - the SNES context
35349d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
353537ec4e1aSPeter Brune 
353637ec4e1aSPeter Brune    Options Database Keys:
35373d5a8a6aSBarry Smith +    -snes_lag_jacobian_persists <true,false> - sets the persistence
35383d5a8a6aSBarry Smith .    -snes_lag_jacobian <-2,1,2,...> - sets the lag
35393d5a8a6aSBarry Smith .    -snes_lag_preconditioner_persists <true,false> - sets the persistence
35403d5a8a6aSBarry Smith -    -snes_lag_preconditioner <-2,1,2,...> - sets the lag
354137ec4e1aSPeter Brune 
354295452b02SPatrick Sanan    Notes:
354395452b02SPatrick Sanan     This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
354437ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
354537ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
354637ec4e1aSPeter Brune 
354737ec4e1aSPeter Brune    Level: developer
354837ec4e1aSPeter Brune 
35493d5a8a6aSBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC(), SNESSetLagPreconditioner()
355037ec4e1aSPeter Brune 
355137ec4e1aSPeter Brune @*/
355237ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
355337ec4e1aSPeter Brune {
355437ec4e1aSPeter Brune   PetscFunctionBegin;
355537ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
355637ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
355737ec4e1aSPeter Brune   snes->lagpre_persist = flg;
355837ec4e1aSPeter Brune   PetscFunctionReturn(0);
355937ec4e1aSPeter Brune }
356037ec4e1aSPeter Brune 
35619b94acceSBarry Smith /*@
3562be5caee7SBarry Smith    SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm
3563be5caee7SBarry Smith 
3564be5caee7SBarry Smith    Logically Collective on SNES
3565be5caee7SBarry Smith 
3566be5caee7SBarry Smith    Input Parameters:
3567be5caee7SBarry Smith +  snes - the SNES context
3568be5caee7SBarry Smith -  force - PETSC_TRUE require at least one iteration
3569be5caee7SBarry Smith 
3570be5caee7SBarry Smith    Options Database Keys:
3571be5caee7SBarry Smith .    -snes_force_iteration <force> - Sets forcing an iteration
3572be5caee7SBarry Smith 
3573be5caee7SBarry Smith    Notes:
3574be5caee7SBarry Smith    This is used sometimes with TS to prevent TS from detecting a false steady state solution
3575be5caee7SBarry Smith 
3576be5caee7SBarry Smith    Level: intermediate
3577be5caee7SBarry Smith 
3578be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
3579be5caee7SBarry Smith @*/
3580be5caee7SBarry Smith PetscErrorCode  SNESSetForceIteration(SNES snes,PetscBool force)
3581be5caee7SBarry Smith {
3582be5caee7SBarry Smith   PetscFunctionBegin;
3583be5caee7SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3584be5caee7SBarry Smith   snes->forceiteration = force;
3585be5caee7SBarry Smith   PetscFunctionReturn(0);
3586be5caee7SBarry Smith }
3587be5caee7SBarry Smith 
358885216dc7SFande Kong /*@
358985216dc7SFande Kong    SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm
359085216dc7SFande Kong 
359185216dc7SFande Kong    Logically Collective on SNES
359285216dc7SFande Kong 
359385216dc7SFande Kong    Input Parameters:
359485216dc7SFande Kong .  snes - the SNES context
359585216dc7SFande Kong 
359685216dc7SFande Kong    Output Parameter:
359785216dc7SFande Kong .  force - PETSC_TRUE requires at least one iteration.
359885216dc7SFande Kong 
359906dd6b0eSSatish Balay    Level: intermediate
360006dd6b0eSSatish Balay 
360185216dc7SFande Kong .seealso: SNESSetForceIteration(), SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance()
360285216dc7SFande Kong @*/
360385216dc7SFande Kong PetscErrorCode  SNESGetForceIteration(SNES snes,PetscBool *force)
360485216dc7SFande Kong {
360585216dc7SFande Kong   PetscFunctionBegin;
360685216dc7SFande Kong   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
360785216dc7SFande Kong   *force = snes->forceiteration;
360885216dc7SFande Kong   PetscFunctionReturn(0);
360985216dc7SFande Kong }
3610be5caee7SBarry Smith 
3611be5caee7SBarry Smith /*@
3612d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
36139b94acceSBarry Smith 
36143f9fe445SBarry Smith    Logically Collective on SNES
3615c7afd0dbSLois Curfman McInnes 
36169b94acceSBarry Smith    Input Parameters:
3617c7afd0dbSLois Curfman McInnes +  snes - the SNES context
361870441072SBarry Smith .  abstol - absolute convergence tolerance
361933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
36205358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
362133174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3622e71169deSBarry Smith -  maxf - maximum number of function evaluations (-1 indicates no limit)
3623fee21e36SBarry Smith 
362433174efeSLois Curfman McInnes    Options Database Keys:
362570441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3626c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3627c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3628c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3629c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
36309b94acceSBarry Smith 
3631d7a720efSLois Curfman McInnes    Notes:
36329b94acceSBarry Smith    The default maximum number of iterations is 50.
36339b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
36349b94acceSBarry Smith 
363536851e7fSLois Curfman McInnes    Level: intermediate
363636851e7fSLois Curfman McInnes 
3637be5caee7SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetDivergenceTolerance(), SNESSetForceIteration()
36389b94acceSBarry Smith @*/
36397087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
36409b94acceSBarry Smith {
36413a40ed3dSBarry Smith   PetscFunctionBegin;
36420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3643c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3644c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3645c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3646c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3647c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3648c5eb9154SBarry Smith 
3649ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
365057622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3651ab54825eSJed Brown     snes->abstol = abstol;
3652ab54825eSJed Brown   }
3653ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
365457622a8eSBarry 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);
3655ab54825eSJed Brown     snes->rtol = rtol;
3656ab54825eSJed Brown   }
3657ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
365857622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3659c60f73f4SPeter Brune     snes->stol = stol;
3660ab54825eSJed Brown   }
3661ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3662ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3663ab54825eSJed Brown     snes->max_its = maxit;
3664ab54825eSJed Brown   }
3665ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3666e71169deSBarry Smith     if (maxf < -1) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be -1 or nonnegative",maxf);
3667ab54825eSJed Brown     snes->max_funcs = maxf;
3668ab54825eSJed Brown   }
366988976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
36703a40ed3dSBarry Smith   PetscFunctionReturn(0);
36719b94acceSBarry Smith }
36729b94acceSBarry Smith 
3673e4d06f11SPatrick Farrell /*@
3674e4d06f11SPatrick Farrell    SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test.
3675e4d06f11SPatrick Farrell 
3676e4d06f11SPatrick Farrell    Logically Collective on SNES
3677e4d06f11SPatrick Farrell 
3678e4d06f11SPatrick Farrell    Input Parameters:
3679e4d06f11SPatrick Farrell +  snes - the SNES context
3680e4d06f11SPatrick Farrell -  divtol - the divergence tolerance. Use -1 to deactivate the test.
3681e4d06f11SPatrick Farrell 
3682e4d06f11SPatrick Farrell    Options Database Keys:
3683a2b725a8SWilliam Gropp .    -snes_divergence_tolerance <divtol> - Sets divtol
3684e4d06f11SPatrick Farrell 
3685e4d06f11SPatrick Farrell    Notes:
3686e4d06f11SPatrick Farrell    The default divergence tolerance is 1e4.
3687e4d06f11SPatrick Farrell 
3688e4d06f11SPatrick Farrell    Level: intermediate
3689e4d06f11SPatrick Farrell 
3690e4d06f11SPatrick Farrell .seealso: SNESSetTolerances(), SNESGetDivergenceTolerance
3691e4d06f11SPatrick Farrell @*/
3692e4d06f11SPatrick Farrell PetscErrorCode  SNESSetDivergenceTolerance(SNES snes,PetscReal divtol)
3693e4d06f11SPatrick Farrell {
3694e4d06f11SPatrick Farrell   PetscFunctionBegin;
3695e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3696e4d06f11SPatrick Farrell   PetscValidLogicalCollectiveReal(snes,divtol,2);
3697e4d06f11SPatrick Farrell 
3698e4d06f11SPatrick Farrell   if (divtol != PETSC_DEFAULT) {
3699e4d06f11SPatrick Farrell     snes->divtol = divtol;
3700e4d06f11SPatrick Farrell   }
3701e4d06f11SPatrick Farrell   else {
3702e4d06f11SPatrick Farrell     snes->divtol = 1.0e4;
3703e4d06f11SPatrick Farrell   }
3704e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3705e4d06f11SPatrick Farrell }
3706e4d06f11SPatrick Farrell 
37079b94acceSBarry Smith /*@
370833174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
370933174efeSLois Curfman McInnes 
3710c7afd0dbSLois Curfman McInnes    Not Collective
3711c7afd0dbSLois Curfman McInnes 
371233174efeSLois Curfman McInnes    Input Parameters:
3713c7afd0dbSLois Curfman McInnes +  snes - the SNES context
371485385478SLisandro Dalcin .  atol - absolute convergence tolerance
371533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
371633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
371733174efeSLois Curfman McInnes            of the change in the solution between steps
371833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3719c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3720fee21e36SBarry Smith 
372133174efeSLois Curfman McInnes    Notes:
37220298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
372333174efeSLois Curfman McInnes 
372436851e7fSLois Curfman McInnes    Level: intermediate
372536851e7fSLois Curfman McInnes 
372633174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
372733174efeSLois Curfman McInnes @*/
37287087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
372933174efeSLois Curfman McInnes {
37303a40ed3dSBarry Smith   PetscFunctionBegin;
37310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
373285385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
373333174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3734c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
373533174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
373633174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
37373a40ed3dSBarry Smith   PetscFunctionReturn(0);
373833174efeSLois Curfman McInnes }
373933174efeSLois Curfman McInnes 
3740e4d06f11SPatrick Farrell /*@
3741e4d06f11SPatrick Farrell    SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test.
3742e4d06f11SPatrick Farrell 
3743e4d06f11SPatrick Farrell    Not Collective
3744e4d06f11SPatrick Farrell 
3745e4d06f11SPatrick Farrell    Input Parameters:
3746e4d06f11SPatrick Farrell +  snes - the SNES context
3747e4d06f11SPatrick Farrell -  divtol - divergence tolerance
3748e4d06f11SPatrick Farrell 
3749e4d06f11SPatrick Farrell    Level: intermediate
3750e4d06f11SPatrick Farrell 
3751e4d06f11SPatrick Farrell .seealso: SNESSetDivergenceTolerance()
3752e4d06f11SPatrick Farrell @*/
3753e4d06f11SPatrick Farrell PetscErrorCode  SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol)
3754e4d06f11SPatrick Farrell {
3755e4d06f11SPatrick Farrell   PetscFunctionBegin;
3756e4d06f11SPatrick Farrell   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3757e4d06f11SPatrick Farrell   if (divtol) *divtol = snes->divtol;
3758e4d06f11SPatrick Farrell   PetscFunctionReturn(0);
3759e4d06f11SPatrick Farrell }
3760e4d06f11SPatrick Farrell 
376133174efeSLois Curfman McInnes /*@
37629b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
37639b94acceSBarry Smith 
37643f9fe445SBarry Smith    Logically Collective on SNES
3765fee21e36SBarry Smith 
3766c7afd0dbSLois Curfman McInnes    Input Parameters:
3767c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3768c7afd0dbSLois Curfman McInnes -  tol - tolerance
3769c7afd0dbSLois Curfman McInnes 
37709b94acceSBarry Smith    Options Database Key:
3771c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
37729b94acceSBarry Smith 
377336851e7fSLois Curfman McInnes    Level: intermediate
377436851e7fSLois Curfman McInnes 
37752492ecdbSBarry Smith .seealso: SNESSetTolerances()
37769b94acceSBarry Smith @*/
37777087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
37789b94acceSBarry Smith {
37793a40ed3dSBarry Smith   PetscFunctionBegin;
37800700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3781c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
37829b94acceSBarry Smith   snes->deltatol = tol;
37833a40ed3dSBarry Smith   PetscFunctionReturn(0);
37849b94acceSBarry Smith }
37859b94acceSBarry Smith 
3786df9fa365SBarry Smith /*
3787df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3788df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3789df9fa365SBarry Smith    macros instead of functions
3790df9fa365SBarry Smith */
3791d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3792ce1608b8SBarry Smith {
3793dfbe8321SBarry Smith   PetscErrorCode ierr;
3794ce1608b8SBarry Smith 
3795ce1608b8SBarry Smith   PetscFunctionBegin;
37960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3797d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3798ce1608b8SBarry Smith   PetscFunctionReturn(0);
3799ce1608b8SBarry Smith }
3800ce1608b8SBarry Smith 
3801d96771aaSLisandro Dalcin PetscErrorCode  SNESMonitorLGCreate(MPI_Comm comm,const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *lgctx)
3802df9fa365SBarry Smith {
3803dfbe8321SBarry Smith   PetscErrorCode ierr;
3804df9fa365SBarry Smith 
3805df9fa365SBarry Smith   PetscFunctionBegin;
3806d96771aaSLisandro Dalcin   ierr = KSPMonitorLGResidualNormCreate(comm,host,label,x,y,m,n,lgctx);CHKERRQ(ierr);
3807df9fa365SBarry Smith   PetscFunctionReturn(0);
3808df9fa365SBarry Smith }
3809df9fa365SBarry 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()
39494619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3950a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3951cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3952c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3953a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3954c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3955c7afd0dbSLois Curfman McInnes                             the options database.
39569665c990SLois Curfman McInnes 
3957639f9d9dSBarry Smith    Notes:
39586bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3959a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
39606bc08f3fSLois Curfman McInnes    order in which they were set.
3961639f9d9dSBarry Smith 
396295452b02SPatrick Sanan    Fortran Notes:
396395452b02SPatrick Sanan     Only a single monitor function can be set for each SNES object
3964025f1a04SBarry Smith 
396536851e7fSLois Curfman McInnes    Level: intermediate
396636851e7fSLois Curfman McInnes 
3967bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
39689b94acceSBarry Smith @*/
39696e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
39709b94acceSBarry Smith {
3971b90d0a6eSBarry Smith   PetscInt       i;
3972649052a6SBarry Smith   PetscErrorCode ierr;
397378064530SBarry Smith   PetscBool      identical;
3974b90d0a6eSBarry Smith 
39753a40ed3dSBarry Smith   PetscFunctionBegin;
39760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3977b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
397878064530SBarry Smith     ierr = PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical);CHKERRQ(ierr);
397978064530SBarry Smith     if (identical) PetscFunctionReturn(0);
3980649052a6SBarry Smith   }
398178064530SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
39826e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3983b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3984639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
39853a40ed3dSBarry Smith   PetscFunctionReturn(0);
39869b94acceSBarry Smith }
39879b94acceSBarry Smith 
3988a278d85bSSatish Balay /*@
3989a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
39905cd90555SBarry Smith 
39913f9fe445SBarry Smith    Logically Collective on SNES
3992c7afd0dbSLois Curfman McInnes 
39935cd90555SBarry Smith    Input Parameters:
39945cd90555SBarry Smith .  snes - the SNES context
39955cd90555SBarry Smith 
39961a480d89SAdministrator    Options Database Key:
3997a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3998a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3999c7afd0dbSLois Curfman McInnes     set via the options database
40005cd90555SBarry Smith 
40015cd90555SBarry Smith    Notes:
40025cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
40035cd90555SBarry Smith 
400436851e7fSLois Curfman McInnes    Level: intermediate
400536851e7fSLois Curfman McInnes 
4006a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
40075cd90555SBarry Smith @*/
40087087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
40095cd90555SBarry Smith {
4010d952e501SBarry Smith   PetscErrorCode ierr;
4011d952e501SBarry Smith   PetscInt       i;
4012d952e501SBarry Smith 
40135cd90555SBarry Smith   PetscFunctionBegin;
40140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4015d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
4016d952e501SBarry Smith     if (snes->monitordestroy[i]) {
40173c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
4018d952e501SBarry Smith     }
4019d952e501SBarry Smith   }
40205cd90555SBarry Smith   snes->numbermonitors = 0;
40215cd90555SBarry Smith   PetscFunctionReturn(0);
40225cd90555SBarry Smith }
40235cd90555SBarry Smith 
4024bf388a1fSBarry Smith /*MC
4025bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
4026bf388a1fSBarry Smith 
4027bf388a1fSBarry Smith      Synopsis:
4028aaa7dc30SBarry Smith      #include <petscsnes.h>
4029bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
4030bf388a1fSBarry Smith 
40311843f636SBarry Smith      Collective on snes
40321843f636SBarry Smith 
40331843f636SBarry Smith     Input Parameters:
4034bf388a1fSBarry Smith +    snes - the SNES context
4035bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
4036bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
4037bf388a1fSBarry Smith .    gnorm - 2-norm of current step
40381843f636SBarry Smith .    f - 2-norm of function
40391843f636SBarry Smith -    cctx - [optional] convergence context
40401843f636SBarry Smith 
40411843f636SBarry Smith     Output Parameter:
40421843f636SBarry Smith .    reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected
4043bf388a1fSBarry Smith 
4044878cb397SSatish Balay    Level: intermediate
4045bf388a1fSBarry Smith 
4046bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
4047bf388a1fSBarry Smith M*/
4048bf388a1fSBarry Smith 
40499b94acceSBarry Smith /*@C
40509b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
40519b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
40529b94acceSBarry Smith 
40533f9fe445SBarry Smith    Logically Collective on SNES
4054fee21e36SBarry Smith 
4055c7afd0dbSLois Curfman McInnes    Input Parameters:
4056c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4057bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
40580298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
4059cf90aa19SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran)
40609b94acceSBarry Smith 
406136851e7fSLois Curfman McInnes    Level: advanced
406236851e7fSLois Curfman McInnes 
4063e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
40649b94acceSBarry Smith @*/
4065bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
40669b94acceSBarry Smith {
40677f7931b9SBarry Smith   PetscErrorCode ierr;
40687f7931b9SBarry Smith 
40693a40ed3dSBarry Smith   PetscFunctionBegin;
40700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4071e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
40727f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
40737f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
40747f7931b9SBarry Smith   }
4075bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
40767f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
407785385478SLisandro Dalcin   snes->cnvP                  = cctx;
40783a40ed3dSBarry Smith   PetscFunctionReturn(0);
40799b94acceSBarry Smith }
40809b94acceSBarry Smith 
408152baeb72SSatish Balay /*@
4082184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
4083184914b5SBarry Smith 
4084184914b5SBarry Smith    Not Collective
4085184914b5SBarry Smith 
4086184914b5SBarry Smith    Input Parameter:
4087184914b5SBarry Smith .  snes - the SNES context
4088184914b5SBarry Smith 
4089184914b5SBarry Smith    Output Parameter:
40904d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
4091184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
4092184914b5SBarry Smith 
40936a4d7782SBarry Smith    Options Database:
40946a4d7782SBarry Smith .   -snes_converged_reason - prints the reason to standard out
40956a4d7782SBarry Smith 
4096184914b5SBarry Smith    Level: intermediate
4097184914b5SBarry Smith 
409895452b02SPatrick Sanan    Notes:
409995452b02SPatrick Sanan     Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING.
4100184914b5SBarry Smith 
410133866048SMatthew G. Knepley .seealso: SNESSetConvergenceTest(), SNESSetConvergedReason(), SNESConvergedReason
4102184914b5SBarry Smith @*/
41037087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
4104184914b5SBarry Smith {
4105184914b5SBarry Smith   PetscFunctionBegin;
41060700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41074482741eSBarry Smith   PetscValidPointer(reason,2);
4108184914b5SBarry Smith   *reason = snes->reason;
4109184914b5SBarry Smith   PetscFunctionReturn(0);
4110184914b5SBarry Smith }
4111184914b5SBarry Smith 
411233866048SMatthew G. Knepley /*@
411333866048SMatthew G. Knepley    SNESSetConvergedReason - Sets the reason the SNES iteration was stopped.
411433866048SMatthew G. Knepley 
411533866048SMatthew G. Knepley    Not Collective
411633866048SMatthew G. Knepley 
411733866048SMatthew G. Knepley    Input Parameters:
411833866048SMatthew G. Knepley +  snes - the SNES context
411933866048SMatthew G. Knepley -  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
412033866048SMatthew G. Knepley             manual pages for the individual convergence tests for complete lists
412133866048SMatthew G. Knepley 
412233866048SMatthew G. Knepley    Level: intermediate
412333866048SMatthew G. Knepley 
412433866048SMatthew G. Knepley .seealso: SNESGetConvergedReason(), SNESSetConvergenceTest(), SNESConvergedReason
412533866048SMatthew G. Knepley @*/
412633866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason)
412733866048SMatthew G. Knepley {
412833866048SMatthew G. Knepley   PetscFunctionBegin;
412933866048SMatthew G. Knepley   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
413033866048SMatthew G. Knepley   snes->reason = reason;
413133866048SMatthew G. Knepley   PetscFunctionReturn(0);
413233866048SMatthew G. Knepley }
413333866048SMatthew G. Knepley 
4134c9005455SLois Curfman McInnes /*@
4135c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
4136c9005455SLois Curfman McInnes 
41373f9fe445SBarry Smith    Logically Collective on SNES
4138fee21e36SBarry Smith 
4139c7afd0dbSLois Curfman McInnes    Input Parameters:
4140c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
41418c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
4142cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
4143758f92a0SBarry Smith .  na  - size of a and its
414464731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
4145758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
4146c7afd0dbSLois Curfman McInnes 
4147308dcc3eSBarry Smith    Notes:
41480298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
4149308dcc3eSBarry Smith    default array of length 10000 is allocated.
4150308dcc3eSBarry Smith 
4151c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
4152c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
4153c9005455SLois Curfman McInnes    during the section of code that is being timed.
4154c9005455SLois Curfman McInnes 
415536851e7fSLois Curfman McInnes    Level: intermediate
415636851e7fSLois Curfman McInnes 
415708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
4158758f92a0SBarry Smith 
4159c9005455SLois Curfman McInnes @*/
41607087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
4161c9005455SLois Curfman McInnes {
4162308dcc3eSBarry Smith   PetscErrorCode ierr;
4163308dcc3eSBarry Smith 
41643a40ed3dSBarry Smith   PetscFunctionBegin;
41650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41667a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
4167a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
41687a1ec6d4SBarry Smith   if (!a) {
4169308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
4170071fcb05SBarry Smith     ierr = PetscCalloc2(na,&a,na,&its);CHKERRQ(ierr);
4171071fcb05SBarry Smith     snes->conv_hist_alloc = PETSC_TRUE;
4172308dcc3eSBarry Smith   }
4173c9005455SLois Curfman McInnes   snes->conv_hist       = a;
4174758f92a0SBarry Smith   snes->conv_hist_its   = its;
4175758f92a0SBarry Smith   snes->conv_hist_max   = na;
4176a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
4177758f92a0SBarry Smith   snes->conv_hist_reset = reset;
4178758f92a0SBarry Smith   PetscFunctionReturn(0);
4179758f92a0SBarry Smith }
4180758f92a0SBarry Smith 
4181308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4182c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
4183c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
418499e0435eSBarry Smith 
41858cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
4186308dcc3eSBarry Smith {
4187308dcc3eSBarry Smith   mxArray   *mat;
4188308dcc3eSBarry Smith   PetscInt  i;
4189308dcc3eSBarry Smith   PetscReal *ar;
4190308dcc3eSBarry Smith 
4191308dcc3eSBarry Smith   PetscFunctionBegin;
4192308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
4193308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
4194f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
4195308dcc3eSBarry Smith   PetscFunctionReturn(mat);
4196308dcc3eSBarry Smith }
4197308dcc3eSBarry Smith #endif
4198308dcc3eSBarry Smith 
41990c4c9dddSBarry Smith /*@C
4200758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
4201758f92a0SBarry Smith 
42023f9fe445SBarry Smith    Not Collective
4203758f92a0SBarry Smith 
4204758f92a0SBarry Smith    Input Parameter:
4205758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
4206758f92a0SBarry Smith 
4207758f92a0SBarry Smith    Output Parameters:
4208a2b725a8SWilliam Gropp +  a   - array to hold history
4209758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
4210758f92a0SBarry Smith          negative if not converged) for each solve.
4211758f92a0SBarry Smith -  na  - size of a and its
4212758f92a0SBarry Smith 
4213758f92a0SBarry Smith    Notes:
4214758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
4215758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
4216758f92a0SBarry Smith 
4217758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
4218758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
4219758f92a0SBarry Smith    during the section of code that is being timed.
4220758f92a0SBarry Smith 
4221758f92a0SBarry Smith    Level: intermediate
4222758f92a0SBarry Smith 
42235ea7661aSPierre Jolivet .seealso: SNESSetConvergenceHistory()
4224758f92a0SBarry Smith 
4225758f92a0SBarry Smith @*/
42267087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
4227758f92a0SBarry Smith {
4228758f92a0SBarry Smith   PetscFunctionBegin;
42290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4230758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
4231758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
4232758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
42333a40ed3dSBarry Smith   PetscFunctionReturn(0);
4234c9005455SLois Curfman McInnes }
4235c9005455SLois Curfman McInnes 
4236ac226902SBarry Smith /*@C
423776b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
4238eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
42397e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
424076b2cf59SMatthew Knepley 
42413f9fe445SBarry Smith   Logically Collective on SNES
424276b2cf59SMatthew Knepley 
424376b2cf59SMatthew Knepley   Input Parameters:
4244a2b725a8SWilliam Gropp + snes - The nonlinear solver context
4245a2b725a8SWilliam Gropp - func - The function
424676b2cf59SMatthew Knepley 
424776b2cf59SMatthew Knepley   Calling sequence of func:
4248a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step);
424976b2cf59SMatthew Knepley 
425076b2cf59SMatthew Knepley . step - The current step of the iteration
425176b2cf59SMatthew Knepley 
4252fe97e370SBarry Smith   Level: advanced
4253fe97e370SBarry Smith 
4254fe97e370SBarry 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()
4255fe97e370SBarry Smith         This is not used by most users.
425676b2cf59SMatthew Knepley 
42578d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
425876b2cf59SMatthew Knepley @*/
42597087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
426076b2cf59SMatthew Knepley {
426176b2cf59SMatthew Knepley   PetscFunctionBegin;
42620700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
4263e7788613SBarry Smith   snes->ops->update = func;
426476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
426576b2cf59SMatthew Knepley }
426676b2cf59SMatthew Knepley 
42679b94acceSBarry Smith /*
42689b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
42699b94acceSBarry Smith    positive parameter delta.
42709b94acceSBarry Smith 
42719b94acceSBarry Smith     Input Parameters:
4272c7afd0dbSLois Curfman McInnes +   snes - the SNES context
42739b94acceSBarry Smith .   y - approximate solution of linear system
42749b94acceSBarry Smith .   fnorm - 2-norm of current function
4275c7afd0dbSLois Curfman McInnes -   delta - trust region size
42769b94acceSBarry Smith 
42779b94acceSBarry Smith     Output Parameters:
4278c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
42799b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
42809b94acceSBarry Smith     region, and exceeds zero otherwise.
4281c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
42829b94acceSBarry Smith 
42839b94acceSBarry Smith     Note:
428404d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
42859b94acceSBarry Smith     is set to be the maximum allowable step size.
42869b94acceSBarry Smith 
42879b94acceSBarry Smith */
4288dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
42899b94acceSBarry Smith {
4290064f8208SBarry Smith   PetscReal      nrm;
4291ea709b57SSatish Balay   PetscScalar    cnorm;
4292dfbe8321SBarry Smith   PetscErrorCode ierr;
42933a40ed3dSBarry Smith 
42943a40ed3dSBarry Smith   PetscFunctionBegin;
42950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
42960700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
4297c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
4298184914b5SBarry Smith 
4299064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
4300064f8208SBarry Smith   if (nrm > *delta) {
4301064f8208SBarry Smith     nrm     = *delta/nrm;
4302064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
4303064f8208SBarry Smith     cnorm   = nrm;
43042dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
43059b94acceSBarry Smith     *ynorm  = *delta;
43069b94acceSBarry Smith   } else {
43079b94acceSBarry Smith     *gpnorm = 0.0;
4308064f8208SBarry Smith     *ynorm  = nrm;
43099b94acceSBarry Smith   }
43103a40ed3dSBarry Smith   PetscFunctionReturn(0);
43119b94acceSBarry Smith }
43129b94acceSBarry Smith 
431391f3e32bSBarry Smith /*@C
431419a666eeSBarry Smith    SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer
43152a359c20SBarry Smith 
43162a359c20SBarry Smith    Collective on SNES
43172a359c20SBarry Smith 
43182a359c20SBarry Smith    Parameter:
43192a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
43202a359c20SBarry Smith -  viewer - the viewer to display the reason
43212a359c20SBarry Smith 
43222a359c20SBarry Smith 
43232a359c20SBarry Smith    Options Database Keys:
4324ee300463SSatish Balay +  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
4325ee300463SSatish Balay -  -snes_converged_reason ::failed - only print reason and number of iterations when diverged
4326eafd5ff0SAlex Lindsay 
432719a666eeSBarry Smith   Notes:
432819a666eeSBarry Smith      To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default,
432919a666eeSBarry Smith      use PETSC_VIEWER_FAILED to only display a reason if it fails.
43302a359c20SBarry Smith 
43312a359c20SBarry Smith    Level: beginner
43322a359c20SBarry Smith 
433319a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonViewFromOptions(),
433419a666eeSBarry Smith           PetscViewerPushFormat(), PetscViewerPopFormat()
43352a359c20SBarry Smith 
43362a359c20SBarry Smith @*/
433719a666eeSBarry Smith PetscErrorCode  SNESConvergedReasonView(SNES snes,PetscViewer viewer)
43382a359c20SBarry Smith {
433975cca76cSMatthew G. Knepley   PetscViewerFormat format;
43402a359c20SBarry Smith   PetscBool         isAscii;
434175cca76cSMatthew G. Knepley   PetscErrorCode    ierr;
43422a359c20SBarry Smith 
43432a359c20SBarry Smith   PetscFunctionBegin;
434419a666eeSBarry Smith   if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes));
43452a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
43462a359c20SBarry Smith   if (isAscii) {
434775cca76cSMatthew G. Knepley     ierr = PetscViewerGetFormat(viewer, &format);CHKERRQ(ierr);
43482a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
434975cca76cSMatthew G. Knepley     if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
435075cca76cSMatthew G. Knepley       DM              dm;
435175cca76cSMatthew G. Knepley       Vec             u;
435275cca76cSMatthew G. Knepley       PetscDS         prob;
435375cca76cSMatthew G. Knepley       PetscInt        Nf, f;
435495cbbfd3SMatthew G. Knepley       PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *);
435595cbbfd3SMatthew G. Knepley       void            **exactCtx;
435675cca76cSMatthew G. Knepley       PetscReal       error;
435775cca76cSMatthew G. Knepley 
435875cca76cSMatthew G. Knepley       ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
435975cca76cSMatthew G. Knepley       ierr = SNESGetSolution(snes, &u);CHKERRQ(ierr);
436075cca76cSMatthew G. Knepley       ierr = DMGetDS(dm, &prob);CHKERRQ(ierr);
436175cca76cSMatthew G. Knepley       ierr = PetscDSGetNumFields(prob, &Nf);CHKERRQ(ierr);
436295cbbfd3SMatthew G. Knepley       ierr = PetscMalloc2(Nf, &exactSol, Nf, &exactCtx);CHKERRQ(ierr);
436395cbbfd3SMatthew G. Knepley       for (f = 0; f < Nf; ++f) {ierr = PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f]);CHKERRQ(ierr);}
436495cbbfd3SMatthew G. Knepley       ierr = DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error);CHKERRQ(ierr);
436595cbbfd3SMatthew G. Knepley       ierr = PetscFree2(exactSol, exactCtx);CHKERRQ(ierr);
436675cca76cSMatthew G. Knepley       if (error < 1.0e-11) {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n");CHKERRQ(ierr);}
436775cca76cSMatthew G. Knepley       else                 {ierr = PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", error);CHKERRQ(ierr);}
436875cca76cSMatthew G. Knepley     }
4369eafd5ff0SAlex Lindsay     if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) {
43702a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
43712a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
43722a359c20SBarry Smith       } else {
43732a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
43742a359c20SBarry Smith       }
4375eafd5ff0SAlex Lindsay     } else if (snes->reason <= 0) {
43762a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
43772a359c20SBarry 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);
43782a359c20SBarry Smith       } else {
43792a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
43802a359c20SBarry Smith       }
43812a359c20SBarry Smith     }
43822a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
43832a359c20SBarry Smith   }
43842a359c20SBarry Smith   PetscFunctionReturn(0);
43852a359c20SBarry Smith }
43862a359c20SBarry Smith 
438791f3e32bSBarry Smith /*@
438819a666eeSBarry Smith   SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
43892a359c20SBarry Smith 
43902a359c20SBarry Smith   Collective on SNES
43912a359c20SBarry Smith 
43922a359c20SBarry Smith   Input Parameters:
43932a359c20SBarry Smith . snes   - the SNES object
43942a359c20SBarry Smith 
43952a359c20SBarry Smith   Level: intermediate
43962a359c20SBarry Smith 
439719a666eeSBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault(), SNESGetConvergedReason(), SNESConvergedReasonView()
439819a666eeSBarry Smith 
43992a359c20SBarry Smith @*/
440019a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes)
44012a359c20SBarry Smith {
44022a359c20SBarry Smith   PetscErrorCode    ierr;
44032a359c20SBarry Smith   PetscViewer       viewer;
44042a359c20SBarry Smith   PetscBool         flg;
44052a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
44062a359c20SBarry Smith   PetscViewerFormat format;
44072a359c20SBarry Smith 
44082a359c20SBarry Smith   PetscFunctionBegin;
44092a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
44102a359c20SBarry Smith   incall = PETSC_TRUE;
441116413a6aSBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
44122a359c20SBarry Smith   if (flg) {
44132a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
441419a666eeSBarry Smith     ierr = SNESConvergedReasonView(snes,viewer);CHKERRQ(ierr);
44152a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
44162a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
44172a359c20SBarry Smith   }
44182a359c20SBarry Smith   incall = PETSC_FALSE;
44192a359c20SBarry Smith   PetscFunctionReturn(0);
44202a359c20SBarry Smith }
44212a359c20SBarry Smith 
4422487a658cSBarry Smith /*@
4423f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
4424f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
44259b94acceSBarry Smith 
4426c7afd0dbSLois Curfman McInnes    Collective on SNES
4427c7afd0dbSLois Curfman McInnes 
4428b2002411SLois Curfman McInnes    Input Parameters:
4429c7afd0dbSLois Curfman McInnes +  snes - the SNES context
44300298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
443185385478SLisandro Dalcin -  x - the solution vector.
44329b94acceSBarry Smith 
4433b2002411SLois Curfman McInnes    Notes:
44348ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
44358ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
44368ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
44378ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
44388ddd3da0SLois Curfman McInnes 
443936851e7fSLois Curfman McInnes    Level: beginner
444036851e7fSLois Curfman McInnes 
4441c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
44429b94acceSBarry Smith @*/
44437087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
44449b94acceSBarry Smith {
4445dfbe8321SBarry Smith   PetscErrorCode    ierr;
4446ace3abfcSBarry Smith   PetscBool         flg;
4447efd51863SBarry Smith   PetscInt          grid;
44480298fd71SBarry Smith   Vec               xcreated = NULL;
4449caa4e7f2SJed Brown   DM                dm;
4450052efed2SBarry Smith 
44513a40ed3dSBarry Smith   PetscFunctionBegin;
44520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4453a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
4454a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
44550700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
445685385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
445785385478SLisandro Dalcin 
445834b4d3a8SMatthew G. Knepley   /* High level operations using the nonlinear solver */
445906fc46c8SMatthew G. Knepley   {
446006fc46c8SMatthew G. Knepley     PetscViewer       viewer;
446106fc46c8SMatthew G. Knepley     PetscViewerFormat format;
44627c88af5aSMatthew G. Knepley     PetscInt          num;
446306fc46c8SMatthew G. Knepley     PetscBool         flg;
446406fc46c8SMatthew G. Knepley     static PetscBool  incall = PETSC_FALSE;
446506fc46c8SMatthew G. Knepley 
446606fc46c8SMatthew G. Knepley     if (!incall) {
446734b4d3a8SMatthew G. Knepley       /* Estimate the convergence rate of the discretization */
446816413a6aSBarry Smith       ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg);CHKERRQ(ierr);
446906fc46c8SMatthew G. Knepley       if (flg) {
447006fc46c8SMatthew G. Knepley         PetscConvEst conv;
447146079b62SMatthew G. Knepley         DM           dm;
447246079b62SMatthew G. Knepley         PetscReal   *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */
447346079b62SMatthew G. Knepley         PetscInt     Nf;
447406fc46c8SMatthew G. Knepley 
447506fc46c8SMatthew G. Knepley         incall = PETSC_TRUE;
447646079b62SMatthew G. Knepley         ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
447746079b62SMatthew G. Knepley         ierr = DMGetNumFields(dm, &Nf);CHKERRQ(ierr);
4478ca5a3622SMatthew G. Knepley         ierr = PetscCalloc1(Nf, &alpha);CHKERRQ(ierr);
447906fc46c8SMatthew G. Knepley         ierr = PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv);CHKERRQ(ierr);
4480900f6b5bSMatthew G. Knepley         ierr = PetscConvEstSetSolver(conv, (PetscObject) snes);CHKERRQ(ierr);
448106fc46c8SMatthew G. Knepley         ierr = PetscConvEstSetFromOptions(conv);CHKERRQ(ierr);
44820955ed61SMatthew G. Knepley         ierr = PetscConvEstSetUp(conv);CHKERRQ(ierr);
448346079b62SMatthew G. Knepley         ierr = PetscConvEstGetConvRate(conv, alpha);CHKERRQ(ierr);
448406fc46c8SMatthew G. Knepley         ierr = PetscViewerPushFormat(viewer, format);CHKERRQ(ierr);
448506fc46c8SMatthew G. Knepley         ierr = PetscConvEstRateView(conv, alpha, viewer);CHKERRQ(ierr);
448606fc46c8SMatthew G. Knepley         ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
448706fc46c8SMatthew G. Knepley         ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
448806fc46c8SMatthew G. Knepley         ierr = PetscConvEstDestroy(&conv);CHKERRQ(ierr);
448946079b62SMatthew G. Knepley         ierr = PetscFree(alpha);CHKERRQ(ierr);
449006fc46c8SMatthew G. Knepley         incall = PETSC_FALSE;
449106fc46c8SMatthew G. Knepley       }
449234b4d3a8SMatthew G. Knepley       /* Adaptively refine the initial grid */
4493b2588ea6SMatthew G. Knepley       num  = 1;
4494b2588ea6SMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg);CHKERRQ(ierr);
449534b4d3a8SMatthew G. Knepley       if (flg) {
449634b4d3a8SMatthew G. Knepley         DMAdaptor adaptor;
449734b4d3a8SMatthew G. Knepley 
449834b4d3a8SMatthew G. Knepley         incall = PETSC_TRUE;
4499ea13f565SStefano Zampini         ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr);
450034b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
4501b2588ea6SMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
450234b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
450334b4d3a8SMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
450434b4d3a8SMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x);CHKERRQ(ierr);
450534b4d3a8SMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
450634b4d3a8SMatthew G. Knepley         incall = PETSC_FALSE;
450734b4d3a8SMatthew G. Knepley       }
45087c88af5aSMatthew G. Knepley       /* Use grid sequencing to adapt */
45097c88af5aSMatthew G. Knepley       num  = 0;
45107c88af5aSMatthew G. Knepley       ierr = PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL);CHKERRQ(ierr);
45117c88af5aSMatthew G. Knepley       if (num) {
45127c88af5aSMatthew G. Knepley         DMAdaptor adaptor;
45137c88af5aSMatthew G. Knepley 
45147c88af5aSMatthew G. Knepley         incall = PETSC_TRUE;
4515ea13f565SStefano Zampini         ierr = DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor);CHKERRQ(ierr);
45167c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSolver(adaptor, snes);CHKERRQ(ierr);
45177c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetSequenceLength(adaptor, num);CHKERRQ(ierr);
45187c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetFromOptions(adaptor);CHKERRQ(ierr);
45197c88af5aSMatthew G. Knepley         ierr = DMAdaptorSetUp(adaptor);CHKERRQ(ierr);
45207c88af5aSMatthew G. Knepley         ierr = DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x);CHKERRQ(ierr);
45217c88af5aSMatthew G. Knepley         ierr = DMAdaptorDestroy(&adaptor);CHKERRQ(ierr);
45227c88af5aSMatthew G. Knepley         incall = PETSC_FALSE;
45237c88af5aSMatthew G. Knepley       }
452406fc46c8SMatthew G. Knepley     }
452506fc46c8SMatthew G. Knepley   }
4526caa4e7f2SJed Brown   if (!x) {
4527caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4528caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
4529a69afd8bSBarry Smith     x    = xcreated;
4530a69afd8bSBarry Smith   }
4531ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
4532f05ece33SBarry Smith 
4533ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
4534efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
4535efd51863SBarry Smith 
453685385478SLisandro Dalcin     /* set solution vector */
4537efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
45386bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
453985385478SLisandro Dalcin     snes->vec_sol = x;
4540caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4541caa4e7f2SJed Brown 
4542caa4e7f2SJed Brown     /* set affine vector if provided */
454385385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
45446bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
454585385478SLisandro Dalcin     snes->vec_rhs = b;
454685385478SLisandro Dalcin 
4547bfdd6862SPatrick 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");
4548154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
4549154060b5SMatthew 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");
4550154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
4551154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
4552154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
4553154060b5SMatthew G. Knepley     }
4554154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
455570e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
45563f149594SLisandro Dalcin 
45577eee914bSBarry Smith     if (!grid) {
45587eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
4559d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
4560d25893d9SBarry Smith       }
4561dd568438SSatish Balay     }
4562d25893d9SBarry Smith 
4563abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
4564971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
4565d5e45103SBarry Smith 
45663f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
45674936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
456885385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
456917186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
4570422a814eSBarry Smith     snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */
45713f149594SLisandro Dalcin 
457237ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
457337ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
457437ec4e1aSPeter Brune 
457516413a6aSBarry Smith     ierr = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg);CHKERRQ(ierr);
4576da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
457719a666eeSBarry Smith     ierr = SNESConvergedReasonViewFromOptions(snes);CHKERRQ(ierr);
45785968eb51SBarry Smith 
4579ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
45809c8e83a9SBarry Smith     if (snes->reason < 0) break;
4581efd51863SBarry Smith     if (grid <  snes->gridsequence) {
4582efd51863SBarry Smith       DM  fine;
4583efd51863SBarry Smith       Vec xnew;
4584efd51863SBarry Smith       Mat interp;
4585efd51863SBarry Smith 
4586ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
4587ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
45880298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
4589efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
4590efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
4591c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
4592efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
4593efd51863SBarry Smith       x    = xnew;
4594efd51863SBarry Smith 
4595efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
4596efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
4597352f405dSMatthew G. Knepley       ierr = SNESResetFromOptions(snes);CHKERRQ(ierr);
4598efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
4599ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
4600efd51863SBarry Smith     }
4601efd51863SBarry Smith   }
4602ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
4603685405a1SBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution");CHKERRQ(ierr);
4604c0f0dcc3SMatthew G. Knepley   ierr = DMMonitor(snes->dm);CHKERRQ(ierr);
46053f7e2da0SPeter Brune 
4606a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
4607e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
46083a40ed3dSBarry Smith   PetscFunctionReturn(0);
46099b94acceSBarry Smith }
46109b94acceSBarry Smith 
46119b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
46129b94acceSBarry Smith 
461382bf6240SBarry Smith /*@C
46144b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
46159b94acceSBarry Smith 
4616fee21e36SBarry Smith    Collective on SNES
4617fee21e36SBarry Smith 
4618c7afd0dbSLois Curfman McInnes    Input Parameters:
4619c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4620454a90a3SBarry Smith -  type - a known method
4621c7afd0dbSLois Curfman McInnes 
4622c7afd0dbSLois Curfman McInnes    Options Database Key:
4623454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
462404d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
4625ae12b187SLois Curfman McInnes 
46269b94acceSBarry Smith    Notes:
4627e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
462804d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
4629c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
4630a2b725a8SWilliam Gropp -    SNESNEWTONTR - Newton's method with trust region
4631c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
46329b94acceSBarry Smith 
4633ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
4634ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
4635ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
4636ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
4637ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
4638ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
4639ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
4640ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
4641ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
4642b0a32e0cSBarry Smith   appropriate method.
464336851e7fSLois Curfman McInnes 
464495452b02SPatrick Sanan     Developer Notes:
464595452b02SPatrick Sanan     SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
46468f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
46478f6c3df8SBarry Smith 
464836851e7fSLois Curfman McInnes   Level: intermediate
4649a703fe33SLois Curfman McInnes 
46508f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
4651435da068SBarry Smith 
46529b94acceSBarry Smith @*/
465319fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
46549b94acceSBarry Smith {
4655dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
4656ace3abfcSBarry Smith   PetscBool      match;
46573a40ed3dSBarry Smith 
46583a40ed3dSBarry Smith   PetscFunctionBegin;
46590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
46604482741eSBarry Smith   PetscValidCharPointer(type,2);
466182bf6240SBarry Smith 
4662251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
46630f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
466492ff6ae8SBarry Smith 
46651c9cd337SJed Brown   ierr = PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
4666e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
466775396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
4668b5c23020SJed Brown   if (snes->ops->destroy) {
4669b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
46700298fd71SBarry Smith     snes->ops->destroy = NULL;
4671b5c23020SJed Brown   }
467275396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
46739e5d0892SLisandro Dalcin   snes->ops->setup          = NULL;
46749e5d0892SLisandro Dalcin   snes->ops->solve          = NULL;
46759e5d0892SLisandro Dalcin   snes->ops->view           = NULL;
46769e5d0892SLisandro Dalcin   snes->ops->setfromoptions = NULL;
46779e5d0892SLisandro Dalcin   snes->ops->destroy        = NULL;
46787fe760d5SStefano Zampini 
46797fe760d5SStefano Zampini   /* It may happen the user has customized the line search before calling SNESSetType */
46807fe760d5SStefano Zampini   if (((PetscObject)snes)->type_name) {
4681d8d34be6SBarry Smith     ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
46827fe760d5SStefano Zampini   }
46837fe760d5SStefano Zampini 
468475396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
468575396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
4686f5af7f23SKarl Rupp 
4687454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
468803bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
46893a40ed3dSBarry Smith   PetscFunctionReturn(0);
46909b94acceSBarry Smith }
46919b94acceSBarry Smith 
46929b94acceSBarry Smith /*@C
46939a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
46949b94acceSBarry Smith 
4695c7afd0dbSLois Curfman McInnes    Not Collective
4696c7afd0dbSLois Curfman McInnes 
46979b94acceSBarry Smith    Input Parameter:
46984b0e389bSBarry Smith .  snes - nonlinear solver context
46999b94acceSBarry Smith 
47009b94acceSBarry Smith    Output Parameter:
47013a7fca6bSBarry Smith .  type - SNES method (a character string)
47029b94acceSBarry Smith 
470336851e7fSLois Curfman McInnes    Level: intermediate
470436851e7fSLois Curfman McInnes 
47059b94acceSBarry Smith @*/
470619fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
47079b94acceSBarry Smith {
47083a40ed3dSBarry Smith   PetscFunctionBegin;
47090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47104482741eSBarry Smith   PetscValidPointer(type,2);
47117adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
47123a40ed3dSBarry Smith   PetscFunctionReturn(0);
47139b94acceSBarry Smith }
47149b94acceSBarry Smith 
47153cd8a7caSMatthew G. Knepley /*@
47163cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
47173cd8a7caSMatthew G. Knepley 
4718d083f849SBarry Smith   Logically Collective on SNES
47193cd8a7caSMatthew G. Knepley 
47203cd8a7caSMatthew G. Knepley   Input Parameters:
47213cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
47223cd8a7caSMatthew G. Knepley - u    - the solution vector
47233cd8a7caSMatthew G. Knepley 
47243cd8a7caSMatthew G. Knepley   Level: beginner
47253cd8a7caSMatthew G. Knepley 
47263cd8a7caSMatthew G. Knepley @*/
47273cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
47283cd8a7caSMatthew G. Knepley {
47293cd8a7caSMatthew G. Knepley   DM             dm;
47303cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
47313cd8a7caSMatthew G. Knepley 
47323cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
47333cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
47343cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
47353cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
47363cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
47373cd8a7caSMatthew G. Knepley 
47383cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
47393cd8a7caSMatthew G. Knepley 
47403cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
47413cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
47423cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
47433cd8a7caSMatthew G. Knepley }
47443cd8a7caSMatthew G. Knepley 
474552baeb72SSatish Balay /*@
47469b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4747c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
47489b94acceSBarry Smith 
4749c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4750c7afd0dbSLois Curfman McInnes 
47519b94acceSBarry Smith    Input Parameter:
47529b94acceSBarry Smith .  snes - the SNES context
47539b94acceSBarry Smith 
47549b94acceSBarry Smith    Output Parameter:
47559b94acceSBarry Smith .  x - the solution
47569b94acceSBarry Smith 
475770e92668SMatthew Knepley    Level: intermediate
475836851e7fSLois Curfman McInnes 
475985385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
47609b94acceSBarry Smith @*/
47617087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
47629b94acceSBarry Smith {
47633a40ed3dSBarry Smith   PetscFunctionBegin;
47640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47654482741eSBarry Smith   PetscValidPointer(x,2);
476685385478SLisandro Dalcin   *x = snes->vec_sol;
476770e92668SMatthew Knepley   PetscFunctionReturn(0);
476870e92668SMatthew Knepley }
476970e92668SMatthew Knepley 
477052baeb72SSatish Balay /*@
47719b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
47729b94acceSBarry Smith    stored.
47739b94acceSBarry Smith 
4774c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4775c7afd0dbSLois Curfman McInnes 
47769b94acceSBarry Smith    Input Parameter:
47779b94acceSBarry Smith .  snes - the SNES context
47789b94acceSBarry Smith 
47799b94acceSBarry Smith    Output Parameter:
47809b94acceSBarry Smith .  x - the solution update
47819b94acceSBarry Smith 
478236851e7fSLois Curfman McInnes    Level: advanced
478336851e7fSLois Curfman McInnes 
478485385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
47859b94acceSBarry Smith @*/
47867087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
47879b94acceSBarry Smith {
47883a40ed3dSBarry Smith   PetscFunctionBegin;
47890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47904482741eSBarry Smith   PetscValidPointer(x,2);
479185385478SLisandro Dalcin   *x = snes->vec_sol_update;
47923a40ed3dSBarry Smith   PetscFunctionReturn(0);
47939b94acceSBarry Smith }
47949b94acceSBarry Smith 
47959b94acceSBarry Smith /*@C
47963638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
47979b94acceSBarry Smith 
4798a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4799c7afd0dbSLois Curfman McInnes 
48009b94acceSBarry Smith    Input Parameter:
48019b94acceSBarry Smith .  snes - the SNES context
48029b94acceSBarry Smith 
48039b94acceSBarry Smith    Output Parameter:
48040298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4805f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
48060298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
48079b94acceSBarry Smith 
480836851e7fSLois Curfman McInnes    Level: advanced
480936851e7fSLois Curfman McInnes 
481004edfde5SBarry Smith     Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function
481104edfde5SBarry Smith 
4812bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
48139b94acceSBarry Smith @*/
4814f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
48159b94acceSBarry Smith {
4816a63bb30eSJed Brown   PetscErrorCode ierr;
48176cab3a1bSJed Brown   DM             dm;
4818a63bb30eSJed Brown 
48193a40ed3dSBarry Smith   PetscFunctionBegin;
48200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4821a63bb30eSJed Brown   if (r) {
4822a63bb30eSJed Brown     if (!snes->vec_func) {
4823a63bb30eSJed Brown       if (snes->vec_rhs) {
4824a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4825a63bb30eSJed Brown       } else if (snes->vec_sol) {
4826a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4827a63bb30eSJed Brown       } else if (snes->dm) {
4828a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4829a63bb30eSJed Brown       }
4830a63bb30eSJed Brown     }
4831a63bb30eSJed Brown     *r = snes->vec_func;
4832a63bb30eSJed Brown   }
48336cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4834f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
48353a40ed3dSBarry Smith   PetscFunctionReturn(0);
48369b94acceSBarry Smith }
48379b94acceSBarry Smith 
4838c79ef259SPeter Brune /*@C
4839be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4840c79ef259SPeter Brune 
4841c79ef259SPeter Brune    Input Parameter:
4842c79ef259SPeter Brune .  snes - the SNES context
4843c79ef259SPeter Brune 
4844c79ef259SPeter Brune    Output Parameter:
4845be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
48460298fd71SBarry Smith -  ctx    - the function context (or NULL)
4847c79ef259SPeter Brune 
4848c79ef259SPeter Brune    Level: advanced
4849c79ef259SPeter Brune 
4850be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4851c79ef259SPeter Brune @*/
4852c79ef259SPeter Brune 
4853be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4854646217ecSPeter Brune {
48556cab3a1bSJed Brown   PetscErrorCode ierr;
48566cab3a1bSJed Brown   DM             dm;
48576cab3a1bSJed Brown 
4858646217ecSPeter Brune   PetscFunctionBegin;
4859646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
48606cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4861be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4862646217ecSPeter Brune   PetscFunctionReturn(0);
4863646217ecSPeter Brune }
4864646217ecSPeter Brune 
48653c7409f5SSatish Balay /*@C
48663c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4867d850072dSLois Curfman McInnes    SNES options in the database.
48683c7409f5SSatish Balay 
48693f9fe445SBarry Smith    Logically Collective on SNES
4870fee21e36SBarry Smith 
4871c7afd0dbSLois Curfman McInnes    Input Parameter:
4872c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4873c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4874c7afd0dbSLois Curfman McInnes 
4875d850072dSLois Curfman McInnes    Notes:
4876a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4877c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4878d850072dSLois Curfman McInnes 
487936851e7fSLois Curfman McInnes    Level: advanced
488036851e7fSLois Curfman McInnes 
4881a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
48823c7409f5SSatish Balay @*/
48837087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
48843c7409f5SSatish Balay {
4885dfbe8321SBarry Smith   PetscErrorCode ierr;
48863c7409f5SSatish Balay 
48873a40ed3dSBarry Smith   PetscFunctionBegin;
48880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4889639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
48901cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
489135f5d045SPeter Brune   if (snes->linesearch) {
48927601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
489308b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
489435f5d045SPeter Brune   }
489535f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
48963a40ed3dSBarry Smith   PetscFunctionReturn(0);
48973c7409f5SSatish Balay }
48983c7409f5SSatish Balay 
48993c7409f5SSatish Balay /*@C
4900f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4901d850072dSLois Curfman McInnes    SNES options in the database.
49023c7409f5SSatish Balay 
49033f9fe445SBarry Smith    Logically Collective on SNES
4904fee21e36SBarry Smith 
4905c7afd0dbSLois Curfman McInnes    Input Parameters:
4906c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4907c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4908c7afd0dbSLois Curfman McInnes 
4909d850072dSLois Curfman McInnes    Notes:
4910a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4911c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4912d850072dSLois Curfman McInnes 
491336851e7fSLois Curfman McInnes    Level: advanced
491436851e7fSLois Curfman McInnes 
4915a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
49163c7409f5SSatish Balay @*/
49177087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
49183c7409f5SSatish Balay {
4919dfbe8321SBarry Smith   PetscErrorCode ierr;
49203c7409f5SSatish Balay 
49213a40ed3dSBarry Smith   PetscFunctionBegin;
49220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4923639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
49241cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
492535f5d045SPeter Brune   if (snes->linesearch) {
49267601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
492708b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
492835f5d045SPeter Brune   }
492935f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
49303a40ed3dSBarry Smith   PetscFunctionReturn(0);
49313c7409f5SSatish Balay }
49323c7409f5SSatish Balay 
49339ab63eb5SSatish Balay /*@C
49343c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
49353c7409f5SSatish Balay    SNES options in the database.
49363c7409f5SSatish Balay 
4937c7afd0dbSLois Curfman McInnes    Not Collective
4938c7afd0dbSLois Curfman McInnes 
49393c7409f5SSatish Balay    Input Parameter:
49403c7409f5SSatish Balay .  snes - the SNES context
49413c7409f5SSatish Balay 
49423c7409f5SSatish Balay    Output Parameter:
49433c7409f5SSatish Balay .  prefix - pointer to the prefix string used
49443c7409f5SSatish Balay 
494595452b02SPatrick Sanan    Notes:
494695452b02SPatrick Sanan     On the fortran side, the user should pass in a string 'prefix' of
49479ab63eb5SSatish Balay    sufficient length to hold the prefix.
49489ab63eb5SSatish Balay 
494936851e7fSLois Curfman McInnes    Level: advanced
495036851e7fSLois Curfman McInnes 
4951a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
49523c7409f5SSatish Balay @*/
49537087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
49543c7409f5SSatish Balay {
4955dfbe8321SBarry Smith   PetscErrorCode ierr;
49563c7409f5SSatish Balay 
49573a40ed3dSBarry Smith   PetscFunctionBegin;
49580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4959639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
49603a40ed3dSBarry Smith   PetscFunctionReturn(0);
49613c7409f5SSatish Balay }
49623c7409f5SSatish Balay 
4963b2002411SLois Curfman McInnes 
49643cea93caSBarry Smith /*@C
49651c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
49661c84c290SBarry Smith 
49671c84c290SBarry Smith    Not collective
49681c84c290SBarry Smith 
49691c84c290SBarry Smith    Input Parameters:
49701c84c290SBarry Smith +  name_solver - name of a new user-defined solver
49711c84c290SBarry Smith -  routine_create - routine to create method context
49721c84c290SBarry Smith 
49731c84c290SBarry Smith    Notes:
49741c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
49751c84c290SBarry Smith 
49761c84c290SBarry Smith    Sample usage:
49771c84c290SBarry Smith .vb
4978bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
49791c84c290SBarry Smith .ve
49801c84c290SBarry Smith 
49811c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
49821c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
49831c84c290SBarry Smith    or at runtime via the option
49841c84c290SBarry Smith $     -snes_type my_solver
49851c84c290SBarry Smith 
49861c84c290SBarry Smith    Level: advanced
49871c84c290SBarry Smith 
49881c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
49891c84c290SBarry Smith 
49901c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
49913cea93caSBarry Smith 
49927f6c08e0SMatthew Knepley   Level: advanced
49933cea93caSBarry Smith @*/
4994bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4995b2002411SLois Curfman McInnes {
4996dfbe8321SBarry Smith   PetscErrorCode ierr;
4997b2002411SLois Curfman McInnes 
4998b2002411SLois Curfman McInnes   PetscFunctionBegin;
49991d36bdfdSBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
5000a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
5001b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
5002b2002411SLois Curfman McInnes }
5003da9b6338SBarry Smith 
50047087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
5005da9b6338SBarry Smith {
5006dfbe8321SBarry Smith   PetscErrorCode ierr;
500777431f27SBarry Smith   PetscInt       N,i,j;
5008da9b6338SBarry Smith   Vec            u,uh,fh;
5009da9b6338SBarry Smith   PetscScalar    value;
5010da9b6338SBarry Smith   PetscReal      norm;
5011da9b6338SBarry Smith 
5012da9b6338SBarry Smith   PetscFunctionBegin;
5013da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
5014da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
5015da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
5016da9b6338SBarry Smith 
5017da9b6338SBarry Smith   /* currently only works for sequential */
5018ea13f565SStefano Zampini   ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n");CHKERRQ(ierr);
5019da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
5020da9b6338SBarry Smith   for (i=0; i<N; i++) {
5021da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
5022ea13f565SStefano Zampini     ierr = PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %D\n",i);CHKERRQ(ierr);
5023da9b6338SBarry Smith     for (j=-10; j<11; j++) {
50248b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
5025da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
50263ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
5027da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
5028ea13f565SStefano Zampini       ierr  = PetscPrintf(PetscObjectComm((PetscObject)snes),"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
5029da9b6338SBarry Smith       value = -value;
5030da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
5031da9b6338SBarry Smith     }
5032da9b6338SBarry Smith   }
50336bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
50346bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
5035da9b6338SBarry Smith   PetscFunctionReturn(0);
5036da9b6338SBarry Smith }
503771f87433Sdalcinl 
503871f87433Sdalcinl /*@
5039fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
504071f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
504171f87433Sdalcinl    Newton method.
504271f87433Sdalcinl 
50433f9fe445SBarry Smith    Logically Collective on SNES
504471f87433Sdalcinl 
504571f87433Sdalcinl    Input Parameters:
504671f87433Sdalcinl +  snes - SNES context
504771f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
504871f87433Sdalcinl 
504964ba62caSBarry Smith     Options Database:
505064ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
505164ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
505264ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
505364ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
505464ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
505564ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
505664ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
505764ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
505864ba62caSBarry Smith 
505971f87433Sdalcinl    Notes:
506071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
506171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
506271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
506371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
506471f87433Sdalcinl    solver.
506571f87433Sdalcinl 
506671f87433Sdalcinl    Level: advanced
506771f87433Sdalcinl 
506871f87433Sdalcinl    Reference:
506971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
507071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
507171f87433Sdalcinl 
5072fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
507371f87433Sdalcinl @*/
50747087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
507571f87433Sdalcinl {
507671f87433Sdalcinl   PetscFunctionBegin;
50770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5078acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
507971f87433Sdalcinl   snes->ksp_ewconv = flag;
508071f87433Sdalcinl   PetscFunctionReturn(0);
508171f87433Sdalcinl }
508271f87433Sdalcinl 
508371f87433Sdalcinl /*@
5084fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
508571f87433Sdalcinl    for computing relative tolerance for linear solvers within an
508671f87433Sdalcinl    inexact Newton method.
508771f87433Sdalcinl 
508871f87433Sdalcinl    Not Collective
508971f87433Sdalcinl 
509071f87433Sdalcinl    Input Parameter:
509171f87433Sdalcinl .  snes - SNES context
509271f87433Sdalcinl 
509371f87433Sdalcinl    Output Parameter:
509471f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
509571f87433Sdalcinl 
509671f87433Sdalcinl    Notes:
509771f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
509871f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
509971f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
510071f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
510171f87433Sdalcinl    solver.
510271f87433Sdalcinl 
510371f87433Sdalcinl    Level: advanced
510471f87433Sdalcinl 
510571f87433Sdalcinl    Reference:
510671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
510771f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
510871f87433Sdalcinl 
5109fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
511071f87433Sdalcinl @*/
51117087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
511271f87433Sdalcinl {
511371f87433Sdalcinl   PetscFunctionBegin;
51140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5115534a8f05SLisandro Dalcin   PetscValidBoolPointer(flag,2);
511671f87433Sdalcinl   *flag = snes->ksp_ewconv;
511771f87433Sdalcinl   PetscFunctionReturn(0);
511871f87433Sdalcinl }
511971f87433Sdalcinl 
512071f87433Sdalcinl /*@
5121fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
512271f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
512371f87433Sdalcinl    Newton method.
512471f87433Sdalcinl 
51253f9fe445SBarry Smith    Logically Collective on SNES
512671f87433Sdalcinl 
512771f87433Sdalcinl    Input Parameters:
512871f87433Sdalcinl +    snes - SNES context
512971f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
513071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
513171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
513271f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
513371f87433Sdalcinl              (0 <= gamma2 <= 1)
513471f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
513571f87433Sdalcinl .    alpha2 - power for safeguard
513671f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
513771f87433Sdalcinl 
513871f87433Sdalcinl    Note:
513971f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
514071f87433Sdalcinl 
514171f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
514271f87433Sdalcinl 
514371f87433Sdalcinl    Level: advanced
514471f87433Sdalcinl 
514571f87433Sdalcinl    Reference:
514671f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
514771f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
514871f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
514971f87433Sdalcinl 
5150fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
515171f87433Sdalcinl @*/
5152f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
515371f87433Sdalcinl {
5154fa9f3622SBarry Smith   SNESKSPEW *kctx;
51555fd66863SKarl Rupp 
515671f87433Sdalcinl   PetscFunctionBegin;
51570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5158fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5159e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
5160c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
5161c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
5162c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
5163c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
5164c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
5165c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
5166c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
516771f87433Sdalcinl 
516871f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
516971f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
517071f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
517171f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
517271f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
517371f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
517471f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
517571f87433Sdalcinl 
5176f23aa3ddSBarry 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);
517757622a8eSBarry 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);
517857622a8eSBarry 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);
517957622a8eSBarry 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);
518057622a8eSBarry 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);
518157622a8eSBarry 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);
518271f87433Sdalcinl   PetscFunctionReturn(0);
518371f87433Sdalcinl }
518471f87433Sdalcinl 
518571f87433Sdalcinl /*@
5186fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
518771f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
518871f87433Sdalcinl    Newton method.
518971f87433Sdalcinl 
519071f87433Sdalcinl    Not Collective
519171f87433Sdalcinl 
519271f87433Sdalcinl    Input Parameters:
519371f87433Sdalcinl      snes - SNES context
519471f87433Sdalcinl 
519571f87433Sdalcinl    Output Parameters:
519671f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
519771f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
519871f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
5199bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
520071f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
520171f87433Sdalcinl .    alpha2 - power for safeguard
520271f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
520371f87433Sdalcinl 
520471f87433Sdalcinl    Level: advanced
520571f87433Sdalcinl 
5206fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
520771f87433Sdalcinl @*/
5208bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
520971f87433Sdalcinl {
5210fa9f3622SBarry Smith   SNESKSPEW *kctx;
52115fd66863SKarl Rupp 
521271f87433Sdalcinl   PetscFunctionBegin;
52130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5214fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
5215e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
521671f87433Sdalcinl   if (version)   *version   = kctx->version;
521771f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
521871f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
521971f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
522071f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
522171f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
522271f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
522371f87433Sdalcinl   PetscFunctionReturn(0);
522471f87433Sdalcinl }
522571f87433Sdalcinl 
5226d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
522771f87433Sdalcinl {
522871f87433Sdalcinl   PetscErrorCode ierr;
5229fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
523071f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
523171f87433Sdalcinl 
523271f87433Sdalcinl   PetscFunctionBegin;
5233d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
523430058271SDmitry Karpeev   if (!snes->iter) {
523530058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
523630058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
523730058271SDmitry Karpeev   }
5238f5af7f23SKarl Rupp   else {
523971f87433Sdalcinl     if (kctx->version == 1) {
524071f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
524171f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
524285ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
524371f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
524471f87433Sdalcinl     } else if (kctx->version == 2) {
524585ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
524685ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
524771f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
524871f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
524985ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
525071f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
525185ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
525271f87433Sdalcinl       stol = PetscMax(rtol,stol);
525371f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
525471f87433Sdalcinl       /* safeguard: avoid oversolving */
525530058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
525671f87433Sdalcinl       stol = PetscMax(rtol,stol);
525771f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
5258e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
525971f87433Sdalcinl   }
526071f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
526171f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
526271f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
526357622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
526471f87433Sdalcinl   PetscFunctionReturn(0);
526571f87433Sdalcinl }
526671f87433Sdalcinl 
5267d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
526871f87433Sdalcinl {
526971f87433Sdalcinl   PetscErrorCode ierr;
5270fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
527171f87433Sdalcinl   PCSide         pcside;
527271f87433Sdalcinl   Vec            lres;
527371f87433Sdalcinl 
527471f87433Sdalcinl   PetscFunctionBegin;
5275d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
52769e5d0892SLisandro Dalcin   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL);CHKERRQ(ierr);
527771dbe336SPeter Brune   kctx->norm_last = snes->norm;
527871f87433Sdalcinl   if (kctx->version == 1) {
52794f00ce20SMatthew G. Knepley     PC        pc;
52804f00ce20SMatthew G. Knepley     PetscBool isNone;
52814f00ce20SMatthew G. Knepley 
52824f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
52834f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
5284b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
52854f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
528671f87433Sdalcinl       /* KSP residual is true linear residual */
528771f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
528871f87433Sdalcinl     } else {
528971f87433Sdalcinl       /* KSP residual is preconditioned residual */
529071f87433Sdalcinl       /* compute true linear residual norm */
529171f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
529271f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
529371f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
529471f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
52956bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
529671f87433Sdalcinl     }
529771f87433Sdalcinl   }
529871f87433Sdalcinl   PetscFunctionReturn(0);
529971f87433Sdalcinl }
530071f87433Sdalcinl 
5301d4211eb9SBarry Smith /*@
5302d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
5303d4211eb9SBarry Smith 
5304d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
5305d4211eb9SBarry Smith 
5306d4211eb9SBarry Smith    Input Parameter:
5307d4211eb9SBarry Smith .  snes - the SNES context
5308d4211eb9SBarry Smith 
5309d4211eb9SBarry Smith    Output Parameter:
5310d4211eb9SBarry Smith .  ksp - the KSP context
5311d4211eb9SBarry Smith 
5312d4211eb9SBarry Smith    Notes:
5313d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
5314d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
5315d4211eb9SBarry Smith    PC contexts as well.
5316d4211eb9SBarry Smith 
5317d4211eb9SBarry Smith    Level: beginner
5318d4211eb9SBarry Smith 
5319d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
5320d4211eb9SBarry Smith @*/
5321d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
532271f87433Sdalcinl {
532371f87433Sdalcinl   PetscErrorCode ierr;
532471f87433Sdalcinl 
532571f87433Sdalcinl   PetscFunctionBegin;
5326d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5327d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
5328d4211eb9SBarry Smith 
5329d4211eb9SBarry Smith   if (!snes->ksp) {
5330a5c2985bSBarry Smith     PetscBool monitor = PETSC_FALSE;
5331a5c2985bSBarry Smith 
5332d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
5333d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
53343bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
5335d4211eb9SBarry Smith 
5336d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
5337d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
5338a5c2985bSBarry Smith 
5339c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
5340a5c2985bSBarry Smith     if (monitor) {
5341a5c2985bSBarry Smith       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
5342a5c2985bSBarry Smith     }
5343e5f7ee39SBarry Smith     monitor = PETSC_FALSE;
5344c5929fdfSBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
5345e5f7ee39SBarry Smith     if (monitor) {
5346e5f7ee39SBarry Smith       PetscObject *objs;
53478b0b5a47SLisandro Dalcin       ierr = KSPMonitorSNESLGResidualNormCreate(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
5348e5f7ee39SBarry Smith       objs[0] = (PetscObject) snes;
5349e5f7ee39SBarry Smith       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
5350e5f7ee39SBarry Smith     }
535116413a6aSBarry Smith     ierr = PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options);CHKERRQ(ierr);
5352d4211eb9SBarry Smith   }
5353d4211eb9SBarry Smith   *ksp = snes->ksp;
535471f87433Sdalcinl   PetscFunctionReturn(0);
535571f87433Sdalcinl }
53566c699258SBarry Smith 
5357d4211eb9SBarry Smith 
5358af0996ceSBarry Smith #include <petsc/private/dmimpl.h>
53596c699258SBarry Smith /*@
53602a808120SBarry Smith    SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners
53616c699258SBarry Smith 
53623f9fe445SBarry Smith    Logically Collective on SNES
53636c699258SBarry Smith 
53646c699258SBarry Smith    Input Parameters:
53652a808120SBarry Smith +  snes - the nonlinear solver context
53662a808120SBarry Smith -  dm - the dm, cannot be NULL
53676c699258SBarry Smith 
5368e03a659cSJed Brown    Notes:
5369e03a659cSJed Brown    A DM can only be used for solving one problem at a time because information about the problem is stored on the DM,
5370e03a659cSJed Brown    even when not using interfaces like DMSNESSetFunction().  Use DMClone() to get a distinct DM when solving different
5371e03a659cSJed Brown    problems using the same function space.
5372e03a659cSJed Brown 
53736c699258SBarry Smith    Level: intermediate
53746c699258SBarry Smith 
53754c2026ceSFande Kong .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
53766c699258SBarry Smith @*/
53777087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
53786c699258SBarry Smith {
53796c699258SBarry Smith   PetscErrorCode ierr;
5380345fed2cSBarry Smith   KSP            ksp;
5381942e3340SBarry Smith   DMSNES         sdm;
53826c699258SBarry Smith 
53836c699258SBarry Smith   PetscFunctionBegin;
53840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
53852a808120SBarry Smith   PetscValidHeaderSpecific(dm,DM_CLASSID,2);
53862a808120SBarry Smith   ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);
5387942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
538851f4b3c7SToby Isaac     if (snes->dm->dmsnes && !dm->dmsnes) {
5389942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
5390942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
5391f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
53926cab3a1bSJed Brown     }
5393dc822a44SJed Brown     ierr = DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
53946bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
53956cab3a1bSJed Brown   }
53966c699258SBarry Smith   snes->dm     = dm;
5397116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
5398f5af7f23SKarl Rupp 
5399345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
5400345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
5401f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
5402efd4aadfSBarry Smith   if (snes->npc) {
5403efd4aadfSBarry Smith     ierr = SNESSetDM(snes->npc, snes->dm);CHKERRQ(ierr);
5404efd4aadfSBarry Smith     ierr = SNESSetNPCSide(snes,snes->npcside);CHKERRQ(ierr);
54052c155ee1SBarry Smith   }
54066c699258SBarry Smith   PetscFunctionReturn(0);
54076c699258SBarry Smith }
54086c699258SBarry Smith 
54096c699258SBarry Smith /*@
54106c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
54116c699258SBarry Smith 
54123f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
54136c699258SBarry Smith 
54146c699258SBarry Smith    Input Parameter:
54156c699258SBarry Smith . snes - the preconditioner context
54166c699258SBarry Smith 
54176c699258SBarry Smith    Output Parameter:
54186c699258SBarry Smith .  dm - the dm
54196c699258SBarry Smith 
54206c699258SBarry Smith    Level: intermediate
54216c699258SBarry Smith 
54224c2026ceSFande Kong .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
54236c699258SBarry Smith @*/
54247087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
54256c699258SBarry Smith {
54266cab3a1bSJed Brown   PetscErrorCode ierr;
54276cab3a1bSJed Brown 
54286c699258SBarry Smith   PetscFunctionBegin;
54290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
54306cab3a1bSJed Brown   if (!snes->dm) {
5431ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
5432116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
54336cab3a1bSJed Brown   }
54346c699258SBarry Smith   *dm = snes->dm;
54356c699258SBarry Smith   PetscFunctionReturn(0);
54366c699258SBarry Smith }
54370807856dSBarry Smith 
543831823bd8SMatthew G Knepley /*@
5439be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
544031823bd8SMatthew G Knepley 
544131823bd8SMatthew G Knepley   Collective on SNES
544231823bd8SMatthew G Knepley 
544331823bd8SMatthew G Knepley   Input Parameters:
544431823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
544531823bd8SMatthew G Knepley - pc   - the preconditioner object
544631823bd8SMatthew G Knepley 
544731823bd8SMatthew G Knepley   Notes:
5448be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
544931823bd8SMatthew G Knepley   to configure it using the API).
545031823bd8SMatthew G Knepley 
545131823bd8SMatthew G Knepley   Level: developer
545231823bd8SMatthew G Knepley 
54533ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
545431823bd8SMatthew G Knepley @*/
5455be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
545631823bd8SMatthew G Knepley {
545731823bd8SMatthew G Knepley   PetscErrorCode ierr;
545831823bd8SMatthew G Knepley 
545931823bd8SMatthew G Knepley   PetscFunctionBegin;
546031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
546131823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
546231823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
546331823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
5464efd4aadfSBarry Smith   ierr     = SNESDestroy(&snes->npc);CHKERRQ(ierr);
5465efd4aadfSBarry Smith   snes->npc = pc;
5466efd4aadfSBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc);CHKERRQ(ierr);
546731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
546831823bd8SMatthew G Knepley }
546931823bd8SMatthew G Knepley 
547031823bd8SMatthew G Knepley /*@
5471be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
547231823bd8SMatthew G Knepley 
5473951fe5abSBarry Smith   Not Collective; but any changes to the obtained SNES object must be applied collectively
547431823bd8SMatthew G Knepley 
547531823bd8SMatthew G Knepley   Input Parameter:
547631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
547731823bd8SMatthew G Knepley 
547831823bd8SMatthew G Knepley   Output Parameter:
547931823bd8SMatthew G Knepley . pc - preconditioner context
548031823bd8SMatthew G Knepley 
5481b5badacbSBarry Smith   Options Database:
5482b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner
5483b5badacbSBarry Smith 
548495452b02SPatrick Sanan   Notes:
5485b5badacbSBarry Smith     If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created.
5486be95d8f1SBarry Smith 
5487951fe5abSBarry Smith     The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original
5488951fe5abSBarry Smith     SNES during SNESSetUp()
5489951fe5abSBarry Smith 
549031823bd8SMatthew G Knepley   Level: developer
549131823bd8SMatthew G Knepley 
5492951fe5abSBarry Smith .seealso: SNESSetNPC(), SNESHasNPC(), SNES, SNESCreate()
549331823bd8SMatthew G Knepley @*/
5494be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
549531823bd8SMatthew G Knepley {
549631823bd8SMatthew G Knepley   PetscErrorCode ierr;
5497a64e098fSPeter Brune   const char     *optionsprefix;
549831823bd8SMatthew G Knepley 
549931823bd8SMatthew G Knepley   PetscFunctionBegin;
550031823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
550131823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
5502efd4aadfSBarry Smith   if (!snes->npc) {
5503efd4aadfSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc);CHKERRQ(ierr);
5504efd4aadfSBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1);CHKERRQ(ierr);
5505efd4aadfSBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc);CHKERRQ(ierr);
5506a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
5507efd4aadfSBarry Smith     ierr = SNESSetOptionsPrefix(snes->npc,optionsprefix);CHKERRQ(ierr);
5508efd4aadfSBarry Smith     ierr = SNESAppendOptionsPrefix(snes->npc,"npc_");CHKERRQ(ierr);
5509efd4aadfSBarry Smith     ierr = SNESSetCountersReset(snes->npc,PETSC_FALSE);CHKERRQ(ierr);
551031823bd8SMatthew G Knepley   }
5511efd4aadfSBarry Smith   *pc = snes->npc;
551231823bd8SMatthew G Knepley   PetscFunctionReturn(0);
551331823bd8SMatthew G Knepley }
551431823bd8SMatthew G Knepley 
55153ad1a0b9SPatrick Farrell /*@
55163ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
55173ad1a0b9SPatrick Farrell 
55183ad1a0b9SPatrick Farrell   Not Collective
55193ad1a0b9SPatrick Farrell 
55203ad1a0b9SPatrick Farrell   Input Parameter:
55213ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
55223ad1a0b9SPatrick Farrell 
55233ad1a0b9SPatrick Farrell   Output Parameter:
55243ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
55253ad1a0b9SPatrick Farrell 
55263ad1a0b9SPatrick Farrell   Level: developer
55273ad1a0b9SPatrick Farrell 
55283ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
55293ad1a0b9SPatrick Farrell @*/
55303ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
55313ad1a0b9SPatrick Farrell {
55323ad1a0b9SPatrick Farrell   PetscFunctionBegin;
55333ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5534efd4aadfSBarry Smith   *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE);
55353ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
55363ad1a0b9SPatrick Farrell }
55373ad1a0b9SPatrick Farrell 
5538c40d0f55SPeter Brune /*@
5539be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
5540c40d0f55SPeter Brune 
5541c40d0f55SPeter Brune     Logically Collective on SNES
5542c40d0f55SPeter Brune 
5543c40d0f55SPeter Brune     Input Parameter:
5544c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5545c40d0f55SPeter Brune 
5546c40d0f55SPeter Brune     Output Parameter:
5547c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5548c40d0f55SPeter Brune .vb
55492d547940SBarry Smith       PC_LEFT - left preconditioning
55502d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5551c40d0f55SPeter Brune .ve
5552c40d0f55SPeter Brune 
5553c40d0f55SPeter Brune     Options Database Keys:
5554c40d0f55SPeter Brune .   -snes_pc_side <right,left>
5555c40d0f55SPeter Brune 
555695452b02SPatrick Sanan     Notes:
555795452b02SPatrick Sanan     SNESNRICHARDSON and SNESNCG only support left preconditioning.
55582d547940SBarry Smith 
5559c40d0f55SPeter Brune     Level: intermediate
5560c40d0f55SPeter Brune 
5561be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
5562c40d0f55SPeter Brune @*/
5563be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
5564c40d0f55SPeter Brune {
5565c40d0f55SPeter Brune   PetscFunctionBegin;
5566c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5567c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
5568efd4aadfSBarry Smith   snes->npcside= side;
5569c40d0f55SPeter Brune   PetscFunctionReturn(0);
5570c40d0f55SPeter Brune }
5571c40d0f55SPeter Brune 
5572c40d0f55SPeter Brune /*@
5573be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
5574c40d0f55SPeter Brune 
5575c40d0f55SPeter Brune     Not Collective
5576c40d0f55SPeter Brune 
5577c40d0f55SPeter Brune     Input Parameter:
5578c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
5579c40d0f55SPeter Brune 
5580c40d0f55SPeter Brune     Output Parameter:
5581c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
5582c40d0f55SPeter Brune .vb
55832d547940SBarry Smith       PC_LEFT - left preconditioning
55842d547940SBarry Smith       PC_RIGHT - right preconditioning (default for most nonlinear solvers)
5585c40d0f55SPeter Brune .ve
5586c40d0f55SPeter Brune 
5587c40d0f55SPeter Brune     Level: intermediate
5588c40d0f55SPeter Brune 
5589be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
5590c40d0f55SPeter Brune @*/
5591be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
5592c40d0f55SPeter Brune {
5593c40d0f55SPeter Brune   PetscFunctionBegin;
5594c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5595c40d0f55SPeter Brune   PetscValidPointer(side,2);
5596efd4aadfSBarry Smith   *side = snes->npcside;
5597c40d0f55SPeter Brune   PetscFunctionReturn(0);
5598c40d0f55SPeter Brune }
5599c40d0f55SPeter Brune 
56009e764e56SPeter Brune /*@
56017601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
56029e764e56SPeter Brune 
56039e764e56SPeter Brune   Collective on SNES
56049e764e56SPeter Brune 
56059e764e56SPeter Brune   Input Parameters:
56069e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
56079e764e56SPeter Brune - linesearch   - the linesearch object
56089e764e56SPeter Brune 
56099e764e56SPeter Brune   Notes:
56107601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
56119e764e56SPeter Brune   to configure it using the API).
56129e764e56SPeter Brune 
56139e764e56SPeter Brune   Level: developer
56149e764e56SPeter Brune 
56157601faf0SJed Brown .seealso: SNESGetLineSearch()
56169e764e56SPeter Brune @*/
56177601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
56189e764e56SPeter Brune {
56199e764e56SPeter Brune   PetscErrorCode ierr;
56209e764e56SPeter Brune 
56219e764e56SPeter Brune   PetscFunctionBegin;
56229e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
5623f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
56249e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
56259e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
5626f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
5627f5af7f23SKarl Rupp 
56289e764e56SPeter Brune   snes->linesearch = linesearch;
5629f5af7f23SKarl Rupp 
56303bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
56319e764e56SPeter Brune   PetscFunctionReturn(0);
56329e764e56SPeter Brune }
56339e764e56SPeter Brune 
5634a34ceb2aSJed Brown /*@
56357601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
56368141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
56379e764e56SPeter Brune 
56389e764e56SPeter Brune   Not Collective
56399e764e56SPeter Brune 
56409e764e56SPeter Brune   Input Parameter:
56419e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
56429e764e56SPeter Brune 
56439e764e56SPeter Brune   Output Parameter:
56449e764e56SPeter Brune . linesearch - linesearch context
56459e764e56SPeter Brune 
5646162e0bf5SPeter Brune   Level: beginner
56479e764e56SPeter Brune 
5648162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
56499e764e56SPeter Brune @*/
56507601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
56519e764e56SPeter Brune {
56529e764e56SPeter Brune   PetscErrorCode ierr;
56539e764e56SPeter Brune   const char     *optionsprefix;
56549e764e56SPeter Brune 
56559e764e56SPeter Brune   PetscFunctionBegin;
56569e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
56579e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
56589e764e56SPeter Brune   if (!snes->linesearch) {
56599e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
566082f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5661f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5662b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
56639e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
56643bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
56659e764e56SPeter Brune   }
56669e764e56SPeter Brune   *linesearch = snes->linesearch;
56679e764e56SPeter Brune   PetscFunctionReturn(0);
56689e764e56SPeter Brune }
5669