xref: /petsc/src/snes/interface/snes.c (revision 2db13446558346134dc3b699c59fe1d864b3b5ed)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
307475bc1SBarry Smith #include <petscdmshell.h>
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool         SNESRegisterAllCalled = PETSC_FALSE;
60298fd71SBarry Smith PetscFunctionList SNESList              = NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
922c6f798SBarry Smith PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
10be95d8f1SBarry Smith PetscLogEvent SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
14e113a28aSBarry Smith /*@
15e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
16e113a28aSBarry Smith 
173f9fe445SBarry Smith    Logically Collective on SNES
18e113a28aSBarry Smith 
19e113a28aSBarry Smith    Input Parameters:
20e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
21e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
22e113a28aSBarry Smith 
23e113a28aSBarry Smith    Options database keys:
24e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
25e113a28aSBarry Smith 
26e113a28aSBarry Smith    Level: intermediate
27e113a28aSBarry Smith 
28e113a28aSBarry Smith    Notes:
29e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
30e113a28aSBarry Smith     to determine if it has converged.
31e113a28aSBarry Smith 
32e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
33e113a28aSBarry Smith 
34e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
35e113a28aSBarry Smith @*/
367087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
37e113a28aSBarry Smith {
38e113a28aSBarry Smith   PetscFunctionBegin;
39e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
41e113a28aSBarry Smith   snes->errorifnotconverged = flg;
42e113a28aSBarry Smith   PetscFunctionReturn(0);
43e113a28aSBarry Smith }
44e113a28aSBarry Smith 
45e113a28aSBarry Smith #undef __FUNCT__
46e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
47e113a28aSBarry Smith /*@
48e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
49e113a28aSBarry Smith 
50e113a28aSBarry Smith    Not Collective
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Input Parameter:
53e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
54e113a28aSBarry Smith 
55e113a28aSBarry Smith    Output Parameter:
56e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
57e113a28aSBarry Smith 
58e113a28aSBarry Smith    Level: intermediate
59e113a28aSBarry Smith 
60e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
61e113a28aSBarry Smith 
62e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
63e113a28aSBarry Smith @*/
647087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
65e113a28aSBarry Smith {
66e113a28aSBarry Smith   PetscFunctionBegin;
67e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
68e113a28aSBarry Smith   PetscValidPointer(flag,2);
69e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
70e113a28aSBarry Smith   PetscFunctionReturn(0);
71e113a28aSBarry Smith }
72e113a28aSBarry Smith 
73e113a28aSBarry Smith #undef __FUNCT__
744936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
75e725d27bSBarry Smith /*@
76bf388a1fSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not
774936397dSBarry Smith      in the functions domain. For example, negative pressure.
784936397dSBarry Smith 
793f9fe445SBarry Smith    Logically Collective on SNES
804936397dSBarry Smith 
814936397dSBarry Smith    Input Parameters:
826a388c36SPeter Brune .  snes - the SNES context
834936397dSBarry Smith 
8428529972SSatish Balay    Level: advanced
854936397dSBarry Smith 
864936397dSBarry Smith .keywords: SNES, view
874936397dSBarry Smith 
88bf388a1fSBarry Smith .seealso: SNESCreate(), SNESSetFunction(), SNESFunction
894936397dSBarry Smith @*/
907087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
914936397dSBarry Smith {
924936397dSBarry Smith   PetscFunctionBegin;
930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
944936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
954936397dSBarry Smith   PetscFunctionReturn(0);
964936397dSBarry Smith }
974936397dSBarry Smith 
986a388c36SPeter Brune #undef __FUNCT__
996a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1006a388c36SPeter Brune /*@
101c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1026a388c36SPeter Brune 
1036a388c36SPeter Brune    Logically Collective on SNES
1046a388c36SPeter Brune 
1056a388c36SPeter Brune    Input Parameters:
1066a388c36SPeter Brune .  snes - the SNES context
1076a388c36SPeter Brune 
1086a388c36SPeter Brune    Output Parameters:
109bf388a1fSBarry Smith .  domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1106a388c36SPeter Brune 
1116a388c36SPeter Brune    Level: advanced
1126a388c36SPeter Brune 
1136a388c36SPeter Brune .keywords: SNES, view
1146a388c36SPeter Brune 
115bf388a1fSBarry Smith .seealso: SNESSetFunctionDomainError(), SNESComputeFunction()
1166a388c36SPeter Brune @*/
1176a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1186a388c36SPeter Brune {
1196a388c36SPeter Brune   PetscFunctionBegin;
1206a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1216a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1226a388c36SPeter Brune   *domainerror = snes->domainerror;
1236a388c36SPeter Brune   PetscFunctionReturn(0);
1246a388c36SPeter Brune }
1256a388c36SPeter Brune 
12655849f57SBarry Smith #undef __FUNCT__
12755849f57SBarry Smith #define __FUNCT__ "SNESLoad"
12855849f57SBarry Smith /*@C
12955849f57SBarry Smith   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
13055849f57SBarry Smith 
13155849f57SBarry Smith   Collective on PetscViewer
13255849f57SBarry Smith 
13355849f57SBarry Smith   Input Parameters:
13455849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
13555849f57SBarry Smith            some related function before a call to SNESLoad().
13655849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
13755849f57SBarry Smith 
13855849f57SBarry Smith    Level: intermediate
13955849f57SBarry Smith 
14055849f57SBarry Smith   Notes:
14155849f57SBarry Smith    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
14255849f57SBarry Smith 
14355849f57SBarry Smith   Notes for advanced users:
14455849f57SBarry Smith   Most users should not need to know the details of the binary storage
14555849f57SBarry Smith   format, since SNESLoad() and TSView() completely hide these details.
14655849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
14755849f57SBarry Smith   format is
14855849f57SBarry Smith .vb
14955849f57SBarry Smith      has not yet been determined
15055849f57SBarry Smith .ve
15155849f57SBarry Smith 
15255849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
15355849f57SBarry Smith @*/
1542d53ad75SBarry Smith PetscErrorCode  SNESLoad(SNES snes, PetscViewer viewer)
15555849f57SBarry Smith {
15655849f57SBarry Smith   PetscErrorCode ierr;
15755849f57SBarry Smith   PetscBool      isbinary;
15855849f57SBarry Smith   PetscInt       classid;
15955849f57SBarry Smith   char           type[256];
16055849f57SBarry Smith   KSP            ksp;
1612d53ad75SBarry Smith   DM             dm;
1622d53ad75SBarry Smith   DMSNES         dmsnes;
16355849f57SBarry Smith 
16455849f57SBarry Smith   PetscFunctionBegin;
1652d53ad75SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16655849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
16755849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
16855849f57SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
16955849f57SBarry Smith 
17055849f57SBarry Smith   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
171ce94432eSBarry Smith   if (classid != SNES_FILE_CLASSID) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file");
17255849f57SBarry Smith   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
1732d53ad75SBarry Smith   ierr = SNESSetType(snes, type);CHKERRQ(ierr);
1742d53ad75SBarry Smith   if (snes->ops->load) {
1752d53ad75SBarry Smith     ierr = (*snes->ops->load)(snes,viewer);CHKERRQ(ierr);
176f2c2a1b9SBarry Smith   }
1772d53ad75SBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1782d53ad75SBarry Smith   ierr = DMGetDMSNES(dm,&dmsnes);CHKERRQ(ierr);
1792d53ad75SBarry Smith   ierr = DMSNESLoad(dmsnes,viewer);CHKERRQ(ierr);
1802d53ad75SBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
18155849f57SBarry Smith   ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr);
18255849f57SBarry Smith   PetscFunctionReturn(0);
18355849f57SBarry Smith }
1846a388c36SPeter Brune 
1859804daf3SBarry Smith #include <petscdraw.h>
186e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
187e04113cfSBarry Smith #include <petscviewersaws.h>
188bfb97211SBarry Smith #endif
1894936397dSBarry Smith #undef __FUNCT__
1904a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1917e2c5f70SBarry Smith /*@C
1929b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1939b94acceSBarry Smith 
1944c49b128SBarry Smith    Collective on SNES
195fee21e36SBarry Smith 
196c7afd0dbSLois Curfman McInnes    Input Parameters:
197c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
198c7afd0dbSLois Curfman McInnes -  viewer - visualization context
199c7afd0dbSLois Curfman McInnes 
2009b94acceSBarry Smith    Options Database Key:
201c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
2029b94acceSBarry Smith 
2039b94acceSBarry Smith    Notes:
2049b94acceSBarry Smith    The available visualization contexts include
205b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
206b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
207c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
208c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
209c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
2109b94acceSBarry Smith 
2113e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
212b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
2139b94acceSBarry Smith 
21436851e7fSLois Curfman McInnes    Level: beginner
21536851e7fSLois Curfman McInnes 
2169b94acceSBarry Smith .keywords: SNES, view
2179b94acceSBarry Smith 
218b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
2199b94acceSBarry Smith @*/
2207087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
2219b94acceSBarry Smith {
222fa9f3622SBarry Smith   SNESKSPEW      *kctx;
223dfbe8321SBarry Smith   PetscErrorCode ierr;
22494b7f48cSBarry Smith   KSP            ksp;
2257f1410a3SPeter Brune   SNESLineSearch linesearch;
22672a02f06SBarry Smith   PetscBool      iascii,isstring,isbinary,isdraw;
2272d53ad75SBarry Smith   DMSNES         dmsnes;
228e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
229536b137fSBarry Smith   PetscBool      issaws;
230bfb97211SBarry Smith #endif
2319b94acceSBarry Smith 
2323a40ed3dSBarry Smith   PetscFunctionBegin;
2330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2343050cee2SBarry Smith   if (!viewer) {
235ce94432eSBarry Smith     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer);CHKERRQ(ierr);
2363050cee2SBarry Smith   }
2370700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
238c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
23974679c65SBarry Smith 
240251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
241251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
24255849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
24372a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
244e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
245536b137fSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);CHKERRQ(ierr);
246bfb97211SBarry Smith #endif
24732077d6dSBarry Smith   if (iascii) {
248dc0571f2SMatthew G. Knepley     SNESNormSchedule normschedule;
249dc0571f2SMatthew G. Knepley 
250dae58748SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer);CHKERRQ(ierr);
251fce1e034SJed Brown     if (!snes->setupcalled) {
252fce1e034SJed Brown       ierr = PetscViewerASCIIPrintf(viewer,"  SNES has not been set up so information may be incomplete\n");CHKERRQ(ierr);
253fce1e034SJed Brown     }
254e7788613SBarry Smith     if (snes->ops->view) {
255b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
256e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
257b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2580ef38995SBarry Smith     }
25977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
26057622a8eSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol);CHKERRQ(ierr);
26177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
26277431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
263dc0571f2SMatthew G. Knepley     ierr = SNESGetNormSchedule(snes, &normschedule);CHKERRQ(ierr);
264dc0571f2SMatthew G. Knepley     if (normschedule > 0) {ierr = PetscViewerASCIIPrintf(viewer,"  norm schedule %s\n",SNESNormSchedules[normschedule]);CHKERRQ(ierr);}
26517fe4bdfSPeter Brune     if (snes->gridsequence) {
26617fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
26717fe4bdfSPeter Brune     }
2689b94acceSBarry Smith     if (snes->ksp_ewconv) {
269fa9f3622SBarry Smith       kctx = (SNESKSPEW*)snes->kspconvctx;
2709b94acceSBarry Smith       if (kctx) {
27177431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
27257622a8eSBarry 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);
27357622a8eSBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2);CHKERRQ(ierr);
2749b94acceSBarry Smith       }
2759b94acceSBarry Smith     }
276eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
277eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
278eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
279eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
280eb1f6c34SBarry Smith     }
281eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
282eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
283eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
28442f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
285eb1f6c34SBarry Smith     }
2860f5bd95cSBarry Smith   } else if (isstring) {
287317d6ea6SBarry Smith     const char *type;
288454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
289b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
29055849f57SBarry Smith   } else if (isbinary) {
29155849f57SBarry Smith     PetscInt    classid = SNES_FILE_CLASSID;
29255849f57SBarry Smith     MPI_Comm    comm;
29355849f57SBarry Smith     PetscMPIInt rank;
29455849f57SBarry Smith     char        type[256];
29555849f57SBarry Smith 
29655849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
29755849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
29855849f57SBarry Smith     if (!rank) {
29955849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
30089d949e2SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type));CHKERRQ(ierr);
30189d949e2SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
30255849f57SBarry Smith     }
30355849f57SBarry Smith     if (snes->ops->view) {
30455849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
30555849f57SBarry Smith     }
30672a02f06SBarry Smith   } else if (isdraw) {
30772a02f06SBarry Smith     PetscDraw draw;
30872a02f06SBarry Smith     char      str[36];
30989fd9fafSBarry Smith     PetscReal x,y,bottom,h;
31072a02f06SBarry Smith 
31172a02f06SBarry Smith     ierr   = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
31272a02f06SBarry Smith     ierr   = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
31372a02f06SBarry Smith     ierr   = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr);
31472a02f06SBarry Smith     ierr   = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr);
3150298fd71SBarry Smith     ierr   = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h);CHKERRQ(ierr);
31689fd9fafSBarry Smith     bottom = y - h;
31772a02f06SBarry Smith     ierr   = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
318c4646bacSPeter Brune     if (snes->ops->view) {
319c4646bacSPeter Brune       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
320c4646bacSPeter Brune     }
321e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
322536b137fSBarry Smith   } else if (issaws) {
323d45a07a7SBarry Smith     PetscMPIInt rank;
3242657e9d9SBarry Smith     const char *name;
325d45a07a7SBarry Smith 
3262657e9d9SBarry Smith     ierr = PetscObjectGetName((PetscObject)snes,&name);CHKERRQ(ierr);
327d45a07a7SBarry Smith     ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
328d45a07a7SBarry Smith     if (!((PetscObject)snes)->amsmem && !rank) {
329d45a07a7SBarry Smith       char       dir[1024];
330d45a07a7SBarry Smith 
331e04113cfSBarry Smith       ierr = PetscObjectViewSAWs((PetscObject)snes,viewer);CHKERRQ(ierr);
3322657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name);CHKERRQ(ierr);
3332657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT));
334bfb97211SBarry Smith       if (!snes->conv_hist) {
335a0931e03SBarry Smith         ierr = SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE);CHKERRQ(ierr);
336bfb97211SBarry Smith       }
3372657e9d9SBarry Smith       ierr = PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name);CHKERRQ(ierr);
3382657e9d9SBarry Smith       PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE));
339f05ece33SBarry Smith     }
340bfb97211SBarry Smith #endif
34172a02f06SBarry Smith   }
34272a02f06SBarry Smith   if (snes->linesearch) {
34372a02f06SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3447601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &linesearch);CHKERRQ(ierr);
34572a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
34672a02f06SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
34719bcc07fSBarry Smith   }
34842f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
3494a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3504a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
3514a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3524a0c5b0cSMatthew G Knepley   }
3532d53ad75SBarry Smith   ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3542d53ad75SBarry Smith   ierr = DMGetDMSNES(snes->dm,&dmsnes);CHKERRQ(ierr);
3552d53ad75SBarry Smith   ierr = DMSNESView(dmsnes, viewer);CHKERRQ(ierr);
3562d53ad75SBarry Smith   ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3572c155ee1SBarry Smith   if (snes->usesksp) {
3582c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
359b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
36094b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
361b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3622c155ee1SBarry Smith   }
36372a02f06SBarry Smith   if (isdraw) {
36472a02f06SBarry Smith     PetscDraw draw;
36572a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
36672a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
3677f1410a3SPeter Brune   }
3683a40ed3dSBarry Smith   PetscFunctionReturn(0);
3699b94acceSBarry Smith }
3709b94acceSBarry Smith 
37176b2cf59SMatthew Knepley /*
37276b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
37376b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
37476b2cf59SMatthew Knepley */
37576b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
376a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
3776849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
37876b2cf59SMatthew Knepley 
379e74ef692SMatthew Knepley #undef __FUNCT__
380e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
381ac226902SBarry Smith /*@C
38276b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
38376b2cf59SMatthew Knepley 
38476b2cf59SMatthew Knepley   Not Collective
38576b2cf59SMatthew Knepley 
38676b2cf59SMatthew Knepley   Input Parameter:
38776b2cf59SMatthew Knepley . snescheck - function that checks for options
38876b2cf59SMatthew Knepley 
38976b2cf59SMatthew Knepley   Level: developer
39076b2cf59SMatthew Knepley 
39176b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
39276b2cf59SMatthew Knepley @*/
3937087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
39476b2cf59SMatthew Knepley {
39576b2cf59SMatthew Knepley   PetscFunctionBegin;
396f23aa3ddSBarry Smith   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
39776b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
39876b2cf59SMatthew Knepley   PetscFunctionReturn(0);
39976b2cf59SMatthew Knepley }
40076b2cf59SMatthew Knepley 
4017087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
402aa3661deSLisandro Dalcin 
403aa3661deSLisandro Dalcin #undef __FUNCT__
404aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
405ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
406aa3661deSLisandro Dalcin {
407aa3661deSLisandro Dalcin   Mat            J;
408aa3661deSLisandro Dalcin   KSP            ksp;
409aa3661deSLisandro Dalcin   PC             pc;
410ace3abfcSBarry Smith   PetscBool      match;
411aa3661deSLisandro Dalcin   PetscErrorCode ierr;
412aa3661deSLisandro Dalcin 
413aa3661deSLisandro Dalcin   PetscFunctionBegin;
4140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
415aa3661deSLisandro Dalcin 
41698613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
41798613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
4182a7a6963SBarry Smith     ierr = MatCreateVecs(A ? A : B, NULL,&snes->vec_func);CHKERRQ(ierr);
41998613b67SLisandro Dalcin   }
42098613b67SLisandro Dalcin 
421aa3661deSLisandro Dalcin   if (version == 1) {
422aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
42398613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4249c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
425aa3661deSLisandro Dalcin   } else if (version == 2) {
426e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
42782a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
428aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
429aa3661deSLisandro Dalcin #else
430e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
431aa3661deSLisandro Dalcin #endif
432a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
433aa3661deSLisandro Dalcin 
434aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
435d3462f78SMatthew Knepley   if (hasOperator) {
4363232da50SPeter Brune 
437aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
438aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
439aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
440aa3661deSLisandro Dalcin   } else {
441aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
4423232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
443172a4300SPeter Brune     if ((snes->pcside == PC_LEFT) && snes->pc) {
444d728fb7dSPeter Brune       if (!snes->jacobian){ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);}
445172a4300SPeter Brune     } else {
44628a52e04SBarry Smith       ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr);
447172a4300SPeter Brune     }
448aa3661deSLisandro Dalcin     /* Force no preconditioner */
449aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
450aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
451251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
452aa3661deSLisandro Dalcin     if (!match) {
453aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
454aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
455aa3661deSLisandro Dalcin     }
456aa3661deSLisandro Dalcin   }
4576bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
458aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
459aa3661deSLisandro Dalcin }
460aa3661deSLisandro Dalcin 
4614a2ae208SSatish Balay #undef __FUNCT__
462dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
463dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
464dfe15315SJed Brown {
465dfe15315SJed Brown   SNES           snes = (SNES)ctx;
466dfe15315SJed Brown   PetscErrorCode ierr;
4670298fd71SBarry Smith   Vec            Xfine,Xfine_named = NULL,Xcoarse;
468dfe15315SJed Brown 
469dfe15315SJed Brown   PetscFunctionBegin;
47016ebb321SJed Brown   if (PetscLogPrintInfo) {
47116ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
47216ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
47316ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
47416ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
47516ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
47616ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
47716ebb321SJed Brown   }
478dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
479dfe15315SJed Brown   else {
480dfe15315SJed Brown     ierr  = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
481dfe15315SJed Brown     Xfine = Xfine_named;
482dfe15315SJed Brown   }
483dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
484dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
485dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
486dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
487dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
488dfe15315SJed Brown   PetscFunctionReturn(0);
489dfe15315SJed Brown }
490dfe15315SJed Brown 
491dfe15315SJed Brown #undef __FUNCT__
49216ebb321SJed Brown #define __FUNCT__ "DMCoarsenHook_SNESVecSol"
49316ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
49416ebb321SJed Brown {
49516ebb321SJed Brown   PetscErrorCode ierr;
49616ebb321SJed Brown 
49716ebb321SJed Brown   PetscFunctionBegin;
49816ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
49916ebb321SJed Brown   PetscFunctionReturn(0);
50016ebb321SJed Brown }
50116ebb321SJed Brown 
50216ebb321SJed Brown #undef __FUNCT__
503caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
504a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
505a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
50623ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx)
507caa4e7f2SJed Brown {
508caa4e7f2SJed Brown   SNES           snes = (SNES)ctx;
509caa4e7f2SJed Brown   PetscErrorCode ierr;
510caa4e7f2SJed Brown   Mat            Asave = A,Bsave = B;
5110298fd71SBarry Smith   Vec            X,Xnamed = NULL;
512dfe15315SJed Brown   DM             dmsave;
5134e269d77SPeter Brune   void           *ctxsave;
514d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
515caa4e7f2SJed Brown 
516caa4e7f2SJed Brown   PetscFunctionBegin;
517dfe15315SJed Brown   dmsave = snes->dm;
518dfe15315SJed Brown   ierr   = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
519dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
520dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
521dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
522dfe15315SJed Brown     X    = Xnamed;
5230298fd71SBarry Smith     ierr = SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave);CHKERRQ(ierr);
5244e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
5258d359177SBarry Smith     if (jac == SNESComputeJacobianDefaultColor) {
5268d359177SBarry Smith       ierr = SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
527dfe15315SJed Brown     }
5284e269d77SPeter Brune   }
5294e269d77SPeter Brune   /* put the previous context back */
5304e269d77SPeter Brune 
531d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,A,B);CHKERRQ(ierr);
5328d359177SBarry Smith   if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) {
5330298fd71SBarry Smith     ierr = SNESSetJacobian(snes,NULL,NULL,jac,ctxsave);CHKERRQ(ierr);
5344e269d77SPeter Brune   }
5354e269d77SPeter Brune 
536ce94432eSBarry Smith   if (A != Asave || B != Bsave) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_SUP,"No support for changing matrices at this time");
537dfe15315SJed Brown   if (Xnamed) {
538dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
539dfe15315SJed Brown   }
540dfe15315SJed Brown   snes->dm = dmsave;
541caa4e7f2SJed Brown   PetscFunctionReturn(0);
542caa4e7f2SJed Brown }
543caa4e7f2SJed Brown 
544caa4e7f2SJed Brown #undef __FUNCT__
5456cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
5466cab3a1bSJed Brown /*@
5476cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
5486cab3a1bSJed Brown 
5496cab3a1bSJed Brown    Collective
5506cab3a1bSJed Brown 
5516cab3a1bSJed Brown    Input Arguments:
5526cab3a1bSJed Brown .  snes - snes to configure
5536cab3a1bSJed Brown 
5546cab3a1bSJed Brown    Level: developer
5556cab3a1bSJed Brown 
5566cab3a1bSJed Brown .seealso: SNESSetUp()
5576cab3a1bSJed Brown @*/
5586cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
5596cab3a1bSJed Brown {
5606cab3a1bSJed Brown   PetscErrorCode ierr;
5616cab3a1bSJed Brown   DM             dm;
562942e3340SBarry Smith   DMSNES         sdm;
5636cab3a1bSJed Brown 
5646cab3a1bSJed Brown   PetscFunctionBegin;
5656cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
566942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
567ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_PLIB,"DMSNES not properly configured");
568f5af7f23SKarl Rupp   else if (!snes->jacobian && snes->mf) {
5696cab3a1bSJed Brown     Mat  J;
5706cab3a1bSJed Brown     void *functx;
5716cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
5726cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5736cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
5740298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
5753232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
5766cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
577caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
5786cab3a1bSJed Brown     Mat J,B;
5796cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
5806cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5816cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
582b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
58306f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
5840298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J,B,NULL,NULL);CHKERRQ(ierr);
5856cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
5866cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
587caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
5886cab3a1bSJed Brown     Mat J,B;
5896cab3a1bSJed Brown     J    = snes->jacobian;
590b412c318SBarry Smith     ierr = DMCreateMatrix(snes->dm,&B);CHKERRQ(ierr);
5910298fd71SBarry Smith     ierr = SNESSetJacobian(snes,J ? J : B,B,NULL,NULL);CHKERRQ(ierr);
5926cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
5936cab3a1bSJed Brown   }
594caa4e7f2SJed Brown   {
595caa4e7f2SJed Brown     KSP ksp;
596caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
597caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
59816ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
599caa4e7f2SJed Brown   }
6006cab3a1bSJed Brown   PetscFunctionReturn(0);
6016cab3a1bSJed Brown }
6026cab3a1bSJed Brown 
6036cab3a1bSJed Brown #undef __FUNCT__
6044a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
6059b94acceSBarry Smith /*@
60694b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
6079b94acceSBarry Smith 
608c7afd0dbSLois Curfman McInnes    Collective on SNES
609c7afd0dbSLois Curfman McInnes 
6109b94acceSBarry Smith    Input Parameter:
6119b94acceSBarry Smith .  snes - the SNES context
6129b94acceSBarry Smith 
61336851e7fSLois Curfman McInnes    Options Database Keys:
614722329fbSBarry Smith +  -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list
61582738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
61682738288SBarry Smith                 of the change in the solution between steps
61770441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
618b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
619b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
620b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
6214839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
622ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
623a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
624e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
625b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
6262492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
62782738288SBarry Smith                                solver; hence iterations will continue until max_it
6281fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
62982738288SBarry Smith                                of convergence test
630e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
631e8105e01SRichard Katz                                        filename given prints to stdout
632a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
633a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
634a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
6354619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
636459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
637e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
638e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
6395968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
640fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
64182738288SBarry Smith 
64282738288SBarry Smith     Options Database for Eisenstat-Walker method:
643fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
6444b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
64536851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
64636851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
64736851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
64836851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
64936851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
65036851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
65182738288SBarry Smith 
65211ca99fdSLois Curfman McInnes    Notes:
65311ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
654a7f22e61SSatish Balay    Users-Manual: ch_snes
65583e2fdc7SBarry Smith 
65636851e7fSLois Curfman McInnes    Level: beginner
65736851e7fSLois Curfman McInnes 
6589b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
6599b94acceSBarry Smith 
66069ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
6619b94acceSBarry Smith @*/
6627087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
6639b94acceSBarry Smith {
6648afaa268SBarry Smith   PetscBool      flg,pcset,persist,set;
665d8f46077SPeter Brune   PetscInt       i,indx,lag,grids;
66604d7464bSBarry Smith   const char     *deft        = SNESNEWTONLS;
66785385478SLisandro Dalcin   const char     *convtests[] = {"default","skip"};
66885385478SLisandro Dalcin   SNESKSPEW      *kctx        = NULL;
669e8105e01SRichard Katz   char           type[256], monfilename[PETSC_MAX_PATH_LEN];
670649052a6SBarry Smith   PetscViewer    monviewer;
67185385478SLisandro Dalcin   PetscErrorCode ierr;
672c40d0f55SPeter Brune   PCSide         pcside;
673a64e098fSPeter Brune   const char     *optionsprefix;
6749b94acceSBarry Smith 
6753a40ed3dSBarry Smith   PetscFunctionBegin;
6760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
6770f51fdf8SToby Isaac   ierr = SNESRegisterAll();CHKERRQ(ierr);
6783194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
679639ff905SBarry Smith   if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name;
680a264d7a6SBarry Smith   ierr = PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
681d64ed03dSBarry Smith   if (flg) {
682186905e3SBarry Smith     ierr = SNESSetType(snes,type);CHKERRQ(ierr);
6837adad957SLisandro Dalcin   } else if (!((PetscObject)snes)->type_name) {
684186905e3SBarry Smith     ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
685d64ed03dSBarry Smith   }
68694ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL);CHKERRQ(ierr);
68794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL);CHKERRQ(ierr);
688186905e3SBarry Smith 
68994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL);CHKERRQ(ierr);
6900298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL);CHKERRQ(ierr);
6910298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL);CHKERRQ(ierr);
6920298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL);CHKERRQ(ierr);
6930298fd71SBarry Smith   ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL);CHKERRQ(ierr);
6940298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL);CHKERRQ(ierr);
69585385478SLisandro Dalcin 
696a8054027SBarry Smith   ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
697a8054027SBarry Smith   if (flg) {
698a8054027SBarry Smith     ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
699a8054027SBarry Smith   }
70037ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
70137ec4e1aSPeter Brune   if (flg) {
70237ec4e1aSPeter Brune     ierr = SNESSetLagPreconditionerPersists(snes,persist);CHKERRQ(ierr);
70337ec4e1aSPeter Brune   }
704e35cf81dSBarry Smith   ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
705e35cf81dSBarry Smith   if (flg) {
706e35cf81dSBarry Smith     ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
707e35cf81dSBarry Smith   }
70837ec4e1aSPeter Brune   ierr = PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg);CHKERRQ(ierr);
70937ec4e1aSPeter Brune   if (flg) {
71037ec4e1aSPeter Brune     ierr = SNESSetLagJacobianPersists(snes,persist);CHKERRQ(ierr);
71137ec4e1aSPeter Brune   }
71237ec4e1aSPeter Brune 
713efd51863SBarry Smith   ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
714efd51863SBarry Smith   if (flg) {
715efd51863SBarry Smith     ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
716efd51863SBarry Smith   }
717a8054027SBarry Smith 
71885385478SLisandro Dalcin   ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
71985385478SLisandro Dalcin   if (flg) {
72085385478SLisandro Dalcin     switch (indx) {
7218d359177SBarry Smith     case 0: ierr = SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL);CHKERRQ(ierr); break;
722e2a6519dSDmitry Karpeev     case 1: ierr = SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL);CHKERRQ(ierr);    break;
72385385478SLisandro Dalcin     }
72485385478SLisandro Dalcin   }
72585385478SLisandro Dalcin 
726365a6726SPeter Brune   ierr = PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg);CHKERRQ(ierr);
727365a6726SPeter Brune   if (flg) { ierr = SNESSetNormSchedule(snes,(SNESNormSchedule)indx);CHKERRQ(ierr); }
728fdacfa88SPeter Brune 
72947073ea2SPeter Brune   ierr = PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg);CHKERRQ(ierr);
73047073ea2SPeter Brune   if (flg) { ierr = SNESSetFunctionType(snes,(SNESFunctionType)indx);CHKERRQ(ierr); }
731186905e3SBarry Smith 
73285385478SLisandro Dalcin   kctx = (SNESKSPEW*)snes->kspconvctx;
73385385478SLisandro Dalcin 
7340298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL);CHKERRQ(ierr);
735186905e3SBarry Smith 
73694ae4db5SBarry Smith   ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL);CHKERRQ(ierr);
73794ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL);CHKERRQ(ierr);
73894ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL);CHKERRQ(ierr);
73994ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL);CHKERRQ(ierr);
74094ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL);CHKERRQ(ierr);
74194ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL);CHKERRQ(ierr);
74294ae4db5SBarry Smith   ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL);CHKERRQ(ierr);
743186905e3SBarry Smith 
74490d69ab7SBarry Smith   flg  = PETSC_FALSE;
7458afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_check_jacobian","Check each Jacobian with a differenced one","SNESUpdateCheckJacobian",flg,&flg,&set);CHKERRQ(ierr);
7468afaa268SBarry Smith   if (set && flg) {
7475341784dSBarry Smith     ierr = SNESSetUpdate(snes,SNESUpdateCheckJacobian);CHKERRQ(ierr);
7485341784dSBarry Smith   }
7495341784dSBarry Smith 
7505341784dSBarry Smith   flg  = PETSC_FALSE;
7518afaa268SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set);CHKERRQ(ierr);
7528afaa268SBarry Smith   if (set && flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
753eabae89aSBarry Smith 
754a6570f20SBarry Smith   ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
755e8105e01SRichard Katz   if (flg) {
756ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr);
757649052a6SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
758e8105e01SRichard Katz   }
759eabae89aSBarry Smith 
760b271bb04SBarry Smith   ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
761b271bb04SBarry Smith   if (flg) {
762b271bb04SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
763b271bb04SBarry Smith   }
764b271bb04SBarry Smith 
765a6570f20SBarry Smith   ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
766eabae89aSBarry Smith   if (flg) {
767ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr);
768f1bef1bcSMatthew Knepley     ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
769e8105e01SRichard Katz   }
770eabae89aSBarry Smith 
771a6570f20SBarry Smith   ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
772eabae89aSBarry Smith   if (flg) {
773ce94432eSBarry Smith     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr);
774649052a6SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
775eabae89aSBarry Smith   }
776eabae89aSBarry Smith 
777*2db13446SMatthew G. Knepley   ierr = PetscOptionsString("-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
778*2db13446SMatthew G. Knepley   if (flg) {
779*2db13446SMatthew G. Knepley     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr);
780*2db13446SMatthew G. Knepley     ierr = SNESMonitorSet(snes,SNESMonitorDefaultField,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
781*2db13446SMatthew G. Knepley   }
782*2db13446SMatthew G. Knepley 
7835180491cSLisandro Dalcin   ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
7845180491cSLisandro Dalcin   if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
7855180491cSLisandro Dalcin 
78690d69ab7SBarry Smith   flg  = PETSC_FALSE;
7870298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,NULL);CHKERRQ(ierr);
788a6570f20SBarry Smith   if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
78990d69ab7SBarry Smith   flg  = PETSC_FALSE;
7900298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,NULL);CHKERRQ(ierr);
791a6570f20SBarry Smith   if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
79290d69ab7SBarry Smith   flg  = PETSC_FALSE;
7930298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,NULL);CHKERRQ(ierr);
794a6570f20SBarry Smith   if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
79590d69ab7SBarry Smith   flg  = PETSC_FALSE;
7960298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,NULL);CHKERRQ(ierr);
797459f5d12SBarry Smith   if (flg) {
7983e7ff0edSBarry Smith     PetscObject *objs;
799459f5d12SBarry Smith 
8003e7ff0edSBarry Smith     ierr = SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&objs);CHKERRQ(ierr);
8013e7ff0edSBarry Smith     ierr = SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorLGResidualNorm,objs,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);CHKERRQ(ierr);
802459f5d12SBarry Smith   }
80390d69ab7SBarry Smith   flg  = PETSC_FALSE;
8040298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL);CHKERRQ(ierr);
805459f5d12SBarry Smith   if (flg) {
806459f5d12SBarry Smith     PetscViewer ctx;
807e24b481bSBarry Smith 
808ce94432eSBarry Smith     ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr);
809459f5d12SBarry Smith     ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
810459f5d12SBarry Smith   }
8112e7541e6SPeter Brune 
8122e7541e6SPeter Brune   flg  = PETSC_FALSE;
8130298fd71SBarry Smith   ierr = PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,NULL);CHKERRQ(ierr);
8142e7541e6SPeter Brune   if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);CHKERRQ(ierr);}
8152e7541e6SPeter Brune 
816cc0c4584SMatthew G. Knepley 
817cc0c4584SMatthew G. Knepley   ierr = PetscOptionsString("-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
818cc0c4584SMatthew G. Knepley   if (flg) {
819cc0c4584SMatthew G. Knepley     ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)snes),monfilename,&monviewer);CHKERRQ(ierr);
820cc0c4584SMatthew G. Knepley     ierr = SNESMonitorSet(snes,SNESMonitorFields,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
821cc0c4584SMatthew G. Knepley   }
822cc0c4584SMatthew G. Knepley 
82390d69ab7SBarry Smith   flg  = PETSC_FALSE;
8248d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL);CHKERRQ(ierr);
8254b27c08aSLois Curfman McInnes   if (flg) {
8266cab3a1bSJed Brown     void *functx;
8270298fd71SBarry Smith     ierr = SNESGetFunction(snes,NULL,NULL,&functx);CHKERRQ(ierr);
8288d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx);CHKERRQ(ierr);
829ae15b995SBarry Smith     ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
8309b94acceSBarry Smith   }
831639f9d9dSBarry Smith 
83244848bc4SPeter Brune   flg  = PETSC_FALSE;
8338d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL);CHKERRQ(ierr);
83497584545SPeter Brune   if (flg) {
8358d359177SBarry Smith     ierr = SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL);CHKERRQ(ierr);
83697584545SPeter Brune   }
83797584545SPeter Brune 
83897584545SPeter Brune   flg  = PETSC_FALSE;
8398d359177SBarry Smith   ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL);CHKERRQ(ierr);
84044848bc4SPeter Brune   if (flg) {
841c52e227fSPeter Brune     DM             dm;
842c52e227fSPeter Brune     DMSNES         sdm;
843c52e227fSPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
844aace71b7SPeter Brune     ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
845aace71b7SPeter Brune     sdm->jacobianctx = NULL;
8468d359177SBarry Smith     ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,0);CHKERRQ(ierr);
84744848bc4SPeter Brune     ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
84844848bc4SPeter Brune   }
84944848bc4SPeter Brune 
850aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
851d8f46077SPeter Brune   ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf_operator,&flg);CHKERRQ(ierr);
852d8f46077SPeter Brune   if (flg && snes->mf_operator) {
853a8248277SBarry Smith     snes->mf_operator = PETSC_TRUE;
854d8f46077SPeter Brune     snes->mf          = PETSC_TRUE;
855a8248277SBarry Smith   }
856aa3661deSLisandro Dalcin   flg  = PETSC_FALSE;
857d8f46077SPeter Brune   ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
858d8f46077SPeter Brune   if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
859d8f46077SPeter Brune   ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
860d28543b3SPeter Brune 
861c40d0f55SPeter Brune   flg  = PETSC_FALSE;
862be95d8f1SBarry Smith   ierr = SNESGetNPCSide(snes,&pcside);CHKERRQ(ierr);
863be95d8f1SBarry Smith   ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
864be95d8f1SBarry Smith   if (flg) {ierr = SNESSetNPCSide(snes,pcside);CHKERRQ(ierr);}
865c40d0f55SPeter Brune 
866e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS)
8678a70d858SHong Zhang   /*
8688a70d858SHong Zhang     Publish convergence information using SAWs
8698a70d858SHong Zhang   */
8708a70d858SHong Zhang   flg  = PETSC_FALSE;
8718a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL);CHKERRQ(ierr);
8728a70d858SHong Zhang   if (flg) {
8738a70d858SHong Zhang     void *ctx;
8748a70d858SHong Zhang     ierr = SNESMonitorSAWsCreate(snes,&ctx);CHKERRQ(ierr);
8758a70d858SHong Zhang     ierr = SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy);CHKERRQ(ierr);
8768a70d858SHong Zhang   }
8778a70d858SHong Zhang #endif
8788a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS)
879b90c6cbeSBarry Smith   {
880b90c6cbeSBarry Smith   PetscBool set;
881b90c6cbeSBarry Smith   flg  = PETSC_FALSE;
8828a70d858SHong Zhang   ierr = PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set);CHKERRQ(ierr);
883b90c6cbeSBarry Smith   if (set) {
884e04113cfSBarry Smith     ierr = PetscObjectSAWsSetBlock((PetscObject)snes,flg);CHKERRQ(ierr);
885b90c6cbeSBarry Smith   }
886b90c6cbeSBarry Smith   }
887b90c6cbeSBarry Smith #endif
888b90c6cbeSBarry Smith 
88976b2cf59SMatthew Knepley   for (i = 0; i < numberofsetfromoptions; i++) {
89076b2cf59SMatthew Knepley     ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
89176b2cf59SMatthew Knepley   }
89276b2cf59SMatthew Knepley 
893e7788613SBarry Smith   if (snes->ops->setfromoptions) {
894e55864a3SBarry Smith     ierr = (*snes->ops->setfromoptions)(PetscOptionsObject,snes);CHKERRQ(ierr);
895639f9d9dSBarry Smith   }
8965d973c19SBarry Smith 
8975d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
8985d973c19SBarry Smith   ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
899b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
9004bbc92c1SBarry Smith 
9019e764e56SPeter Brune   if (!snes->linesearch) {
9027601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
9039e764e56SPeter Brune   }
904f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
9059e764e56SPeter Brune 
9066991f827SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
9076991f827SBarry Smith   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
9086991f827SBarry Smith   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
9096991f827SBarry Smith 
910be95d8f1SBarry Smith   /* if someone has set the SNES NPC type, create it. */
91151e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
91251e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
91351e86f29SPeter Brune   if (pcset && (!snes->pc)) {
914be95d8f1SBarry Smith     ierr = SNESGetNPC(snes, &snes->pc);CHKERRQ(ierr);
91551e86f29SPeter Brune   }
9163a40ed3dSBarry Smith   PetscFunctionReturn(0);
9179b94acceSBarry Smith }
9189b94acceSBarry Smith 
919d25893d9SBarry Smith #undef __FUNCT__
920d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
921bb9467b5SJed Brown /*@C
922d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
923d25893d9SBarry Smith    the nonlinear solvers.
924d25893d9SBarry Smith 
925d25893d9SBarry Smith    Logically Collective on SNES
926d25893d9SBarry Smith 
927d25893d9SBarry Smith    Input Parameters:
928d25893d9SBarry Smith +  snes - the SNES context
929d25893d9SBarry Smith .  compute - function to compute the context
930d25893d9SBarry Smith -  destroy - function to destroy the context
931d25893d9SBarry Smith 
932d25893d9SBarry Smith    Level: intermediate
933d25893d9SBarry Smith 
934bb9467b5SJed Brown    Notes:
935bb9467b5SJed Brown    This function is currently not available from Fortran.
936bb9467b5SJed Brown 
937d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
938d25893d9SBarry Smith 
939d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
940d25893d9SBarry Smith @*/
941d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
942d25893d9SBarry Smith {
943d25893d9SBarry Smith   PetscFunctionBegin;
944d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
945d25893d9SBarry Smith   snes->ops->usercompute = compute;
946d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
947d25893d9SBarry Smith   PetscFunctionReturn(0);
948d25893d9SBarry Smith }
949a847f771SSatish Balay 
9504a2ae208SSatish Balay #undef __FUNCT__
9514a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
952b07ff414SBarry Smith /*@
9539b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
9549b94acceSBarry Smith    the nonlinear solvers.
9559b94acceSBarry Smith 
9563f9fe445SBarry Smith    Logically Collective on SNES
957fee21e36SBarry Smith 
958c7afd0dbSLois Curfman McInnes    Input Parameters:
959c7afd0dbSLois Curfman McInnes +  snes - the SNES context
960c7afd0dbSLois Curfman McInnes -  usrP - optional user context
961c7afd0dbSLois Curfman McInnes 
96236851e7fSLois Curfman McInnes    Level: intermediate
96336851e7fSLois Curfman McInnes 
9649b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
9659b94acceSBarry Smith 
966ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
9679b94acceSBarry Smith @*/
9687087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
9699b94acceSBarry Smith {
9701b2093e4SBarry Smith   PetscErrorCode ierr;
971b07ff414SBarry Smith   KSP            ksp;
9721b2093e4SBarry Smith 
9733a40ed3dSBarry Smith   PetscFunctionBegin;
9740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
975b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
976b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
9779b94acceSBarry Smith   snes->user = usrP;
9783a40ed3dSBarry Smith   PetscFunctionReturn(0);
9799b94acceSBarry Smith }
98074679c65SBarry Smith 
9814a2ae208SSatish Balay #undef __FUNCT__
9824a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
983b07ff414SBarry Smith /*@
9849b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
9859b94acceSBarry Smith    nonlinear solvers.
9869b94acceSBarry Smith 
987c7afd0dbSLois Curfman McInnes    Not Collective
988c7afd0dbSLois Curfman McInnes 
9899b94acceSBarry Smith    Input Parameter:
9909b94acceSBarry Smith .  snes - SNES context
9919b94acceSBarry Smith 
9929b94acceSBarry Smith    Output Parameter:
9939b94acceSBarry Smith .  usrP - user context
9949b94acceSBarry Smith 
99536851e7fSLois Curfman McInnes    Level: intermediate
99636851e7fSLois Curfman McInnes 
9979b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
9989b94acceSBarry Smith 
9999b94acceSBarry Smith .seealso: SNESSetApplicationContext()
10009b94acceSBarry Smith @*/
1001e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
10029b94acceSBarry Smith {
10033a40ed3dSBarry Smith   PetscFunctionBegin;
10040700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1005e71120c6SJed Brown   *(void**)usrP = snes->user;
10063a40ed3dSBarry Smith   PetscFunctionReturn(0);
10079b94acceSBarry Smith }
100874679c65SBarry Smith 
10094a2ae208SSatish Balay #undef __FUNCT__
10104a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
10119b94acceSBarry Smith /*@
1012c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
1013c8228a4eSBarry Smith    at this time.
10149b94acceSBarry Smith 
1015c7afd0dbSLois Curfman McInnes    Not Collective
1016c7afd0dbSLois Curfman McInnes 
10179b94acceSBarry Smith    Input Parameter:
10189b94acceSBarry Smith .  snes - SNES context
10199b94acceSBarry Smith 
10209b94acceSBarry Smith    Output Parameter:
10219b94acceSBarry Smith .  iter - iteration number
10229b94acceSBarry Smith 
1023c8228a4eSBarry Smith    Notes:
1024c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
1025c8228a4eSBarry Smith 
1026c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
102708405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
102808405cd6SLois Curfman McInnes .vb
102908405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
103008405cd6SLois Curfman McInnes       if (!(it % 2)) {
103108405cd6SLois Curfman McInnes         [compute Jacobian here]
103208405cd6SLois Curfman McInnes       }
103308405cd6SLois Curfman McInnes .ve
1034c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
103508405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
1036c8228a4eSBarry Smith 
103736851e7fSLois Curfman McInnes    Level: intermediate
103836851e7fSLois Curfman McInnes 
10392b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
10402b668275SBarry Smith 
104171dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
10429b94acceSBarry Smith @*/
10437087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt *iter)
10449b94acceSBarry Smith {
10453a40ed3dSBarry Smith   PetscFunctionBegin;
10460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10474482741eSBarry Smith   PetscValidIntPointer(iter,2);
10489b94acceSBarry Smith   *iter = snes->iter;
10493a40ed3dSBarry Smith   PetscFunctionReturn(0);
10509b94acceSBarry Smith }
105174679c65SBarry Smith 
10524a2ae208SSatish Balay #undef __FUNCT__
1053360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
1054360c497dSPeter Brune /*@
1055360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
1056360c497dSPeter Brune 
1057360c497dSPeter Brune    Not Collective
1058360c497dSPeter Brune 
1059360c497dSPeter Brune    Input Parameter:
1060360c497dSPeter Brune .  snes - SNES context
1061360c497dSPeter Brune .  iter - iteration number
1062360c497dSPeter Brune 
1063360c497dSPeter Brune    Level: developer
1064360c497dSPeter Brune 
1065360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
1066360c497dSPeter Brune 
106771dbe336SPeter Brune .seealso:   SNESGetLinearSolveIterations()
1068360c497dSPeter Brune @*/
1069360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
1070360c497dSPeter Brune {
1071360c497dSPeter Brune   PetscErrorCode ierr;
1072360c497dSPeter Brune 
1073360c497dSPeter Brune   PetscFunctionBegin;
1074360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1075e04113cfSBarry Smith   ierr       = PetscObjectSAWsTakeAccess((PetscObject)snes);CHKERRQ(ierr);
1076360c497dSPeter Brune   snes->iter = iter;
1077e04113cfSBarry Smith   ierr       = PetscObjectSAWsGrantAccess((PetscObject)snes);CHKERRQ(ierr);
1078360c497dSPeter Brune   PetscFunctionReturn(0);
1079360c497dSPeter Brune }
1080360c497dSPeter Brune 
1081360c497dSPeter Brune #undef __FUNCT__
1082b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
10839b94acceSBarry Smith /*@
1084b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
10859b94acceSBarry Smith    attempted by the nonlinear solver.
10869b94acceSBarry Smith 
1087c7afd0dbSLois Curfman McInnes    Not Collective
1088c7afd0dbSLois Curfman McInnes 
10899b94acceSBarry Smith    Input Parameter:
10909b94acceSBarry Smith .  snes - SNES context
10919b94acceSBarry Smith 
10929b94acceSBarry Smith    Output Parameter:
10939b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
10949b94acceSBarry Smith 
1095c96a6f78SLois Curfman McInnes    Notes:
1096c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1097c96a6f78SLois Curfman McInnes 
109836851e7fSLois Curfman McInnes    Level: intermediate
109936851e7fSLois Curfman McInnes 
11009b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
110158ebbce7SBarry Smith 
1102e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
110358ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
11049b94acceSBarry Smith @*/
11057087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails)
11069b94acceSBarry Smith {
11073a40ed3dSBarry Smith   PetscFunctionBegin;
11080700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11094482741eSBarry Smith   PetscValidIntPointer(nfails,2);
111050ffb88aSMatthew Knepley   *nfails = snes->numFailures;
111150ffb88aSMatthew Knepley   PetscFunctionReturn(0);
111250ffb88aSMatthew Knepley }
111350ffb88aSMatthew Knepley 
111450ffb88aSMatthew Knepley #undef __FUNCT__
1115b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
111650ffb88aSMatthew Knepley /*@
1117b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
111850ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
111950ffb88aSMatthew Knepley 
112050ffb88aSMatthew Knepley    Not Collective
112150ffb88aSMatthew Knepley 
112250ffb88aSMatthew Knepley    Input Parameters:
112350ffb88aSMatthew Knepley +  snes     - SNES context
112450ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
112550ffb88aSMatthew Knepley 
112650ffb88aSMatthew Knepley    Level: intermediate
112750ffb88aSMatthew Knepley 
112850ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
112958ebbce7SBarry Smith 
1130e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
113158ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
113250ffb88aSMatthew Knepley @*/
11337087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
113450ffb88aSMatthew Knepley {
113550ffb88aSMatthew Knepley   PetscFunctionBegin;
11360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
113750ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
113850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
113950ffb88aSMatthew Knepley }
114050ffb88aSMatthew Knepley 
114150ffb88aSMatthew Knepley #undef __FUNCT__
1142b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
114350ffb88aSMatthew Knepley /*@
1144b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
114550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
114650ffb88aSMatthew Knepley 
114750ffb88aSMatthew Knepley    Not Collective
114850ffb88aSMatthew Knepley 
114950ffb88aSMatthew Knepley    Input Parameter:
115050ffb88aSMatthew Knepley .  snes     - SNES context
115150ffb88aSMatthew Knepley 
115250ffb88aSMatthew Knepley    Output Parameter:
115350ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
115450ffb88aSMatthew Knepley 
115550ffb88aSMatthew Knepley    Level: intermediate
115650ffb88aSMatthew Knepley 
115750ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
115858ebbce7SBarry Smith 
1159e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
116058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
116158ebbce7SBarry Smith 
116250ffb88aSMatthew Knepley @*/
11637087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
116450ffb88aSMatthew Knepley {
116550ffb88aSMatthew Knepley   PetscFunctionBegin;
11660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11674482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
116850ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
11693a40ed3dSBarry Smith   PetscFunctionReturn(0);
11709b94acceSBarry Smith }
1171a847f771SSatish Balay 
11724a2ae208SSatish Balay #undef __FUNCT__
11732541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
11742541af92SBarry Smith /*@
11752541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
11762541af92SBarry Smith      done by SNES.
11772541af92SBarry Smith 
11782541af92SBarry Smith    Not Collective
11792541af92SBarry Smith 
11802541af92SBarry Smith    Input Parameter:
11812541af92SBarry Smith .  snes     - SNES context
11822541af92SBarry Smith 
11832541af92SBarry Smith    Output Parameter:
11842541af92SBarry Smith .  nfuncs - number of evaluations
11852541af92SBarry Smith 
11862541af92SBarry Smith    Level: intermediate
11872541af92SBarry Smith 
1188971e163fSPeter Brune    Notes: Reset every time SNESSolve is called unless SNESSetCountersReset() is used.
1189971e163fSPeter Brune 
11902541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
119158ebbce7SBarry Smith 
1192971e163fSPeter Brune .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(), SNESSetCountersReset()
11932541af92SBarry Smith @*/
11947087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
11952541af92SBarry Smith {
11962541af92SBarry Smith   PetscFunctionBegin;
11970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11982541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
11992541af92SBarry Smith   *nfuncs = snes->nfuncs;
12002541af92SBarry Smith   PetscFunctionReturn(0);
12012541af92SBarry Smith }
12022541af92SBarry Smith 
12032541af92SBarry Smith #undef __FUNCT__
12043d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
12053d4c4710SBarry Smith /*@
12063d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
12073d4c4710SBarry Smith    linear solvers.
12083d4c4710SBarry Smith 
12093d4c4710SBarry Smith    Not Collective
12103d4c4710SBarry Smith 
12113d4c4710SBarry Smith    Input Parameter:
12123d4c4710SBarry Smith .  snes - SNES context
12133d4c4710SBarry Smith 
12143d4c4710SBarry Smith    Output Parameter:
12153d4c4710SBarry Smith .  nfails - number of failed solves
12163d4c4710SBarry Smith 
12173d4c4710SBarry Smith    Notes:
12183d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
12193d4c4710SBarry Smith 
12203d4c4710SBarry Smith    Level: intermediate
12213d4c4710SBarry Smith 
12223d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
122358ebbce7SBarry Smith 
1224e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
12253d4c4710SBarry Smith @*/
12267087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails)
12273d4c4710SBarry Smith {
12283d4c4710SBarry Smith   PetscFunctionBegin;
12290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12303d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
12313d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
12323d4c4710SBarry Smith   PetscFunctionReturn(0);
12333d4c4710SBarry Smith }
12343d4c4710SBarry Smith 
12353d4c4710SBarry Smith #undef __FUNCT__
12363d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
12373d4c4710SBarry Smith /*@
12383d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
12393d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
12403d4c4710SBarry Smith 
12413f9fe445SBarry Smith    Logically Collective on SNES
12423d4c4710SBarry Smith 
12433d4c4710SBarry Smith    Input Parameters:
12443d4c4710SBarry Smith +  snes     - SNES context
12453d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
12463d4c4710SBarry Smith 
12473d4c4710SBarry Smith    Level: intermediate
12483d4c4710SBarry Smith 
1249a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
12503d4c4710SBarry Smith 
12513d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
12523d4c4710SBarry Smith 
125358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
12543d4c4710SBarry Smith @*/
12557087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
12563d4c4710SBarry Smith {
12573d4c4710SBarry Smith   PetscFunctionBegin;
12580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1259c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
12603d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
12613d4c4710SBarry Smith   PetscFunctionReturn(0);
12623d4c4710SBarry Smith }
12633d4c4710SBarry Smith 
12643d4c4710SBarry Smith #undef __FUNCT__
12653d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
12663d4c4710SBarry Smith /*@
12673d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
12683d4c4710SBarry Smith      are allowed before SNES terminates
12693d4c4710SBarry Smith 
12703d4c4710SBarry Smith    Not Collective
12713d4c4710SBarry Smith 
12723d4c4710SBarry Smith    Input Parameter:
12733d4c4710SBarry Smith .  snes     - SNES context
12743d4c4710SBarry Smith 
12753d4c4710SBarry Smith    Output Parameter:
12763d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
12773d4c4710SBarry Smith 
12783d4c4710SBarry Smith    Level: intermediate
12793d4c4710SBarry Smith 
12803d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
12813d4c4710SBarry Smith 
12823d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
12833d4c4710SBarry Smith 
1284e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
12853d4c4710SBarry Smith @*/
12867087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
12873d4c4710SBarry Smith {
12883d4c4710SBarry Smith   PetscFunctionBegin;
12890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12903d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
12913d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
12923d4c4710SBarry Smith   PetscFunctionReturn(0);
12933d4c4710SBarry Smith }
12943d4c4710SBarry Smith 
12953d4c4710SBarry Smith #undef __FUNCT__
1296b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1297c96a6f78SLois Curfman McInnes /*@
1298b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1299c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1300c96a6f78SLois Curfman McInnes 
1301c7afd0dbSLois Curfman McInnes    Not Collective
1302c7afd0dbSLois Curfman McInnes 
1303c96a6f78SLois Curfman McInnes    Input Parameter:
1304c96a6f78SLois Curfman McInnes .  snes - SNES context
1305c96a6f78SLois Curfman McInnes 
1306c96a6f78SLois Curfman McInnes    Output Parameter:
1307c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1308c96a6f78SLois Curfman McInnes 
1309c96a6f78SLois Curfman McInnes    Notes:
1310971e163fSPeter Brune    This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used.
1311c96a6f78SLois Curfman McInnes 
131236851e7fSLois Curfman McInnes    Level: intermediate
131336851e7fSLois Curfman McInnes 
1314c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
13152b668275SBarry Smith 
131671dbe336SPeter Brune .seealso:  SNESGetIterationNumber(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESSetCountersReset()
1317c96a6f78SLois Curfman McInnes @*/
13187087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt *lits)
1319c96a6f78SLois Curfman McInnes {
13203a40ed3dSBarry Smith   PetscFunctionBegin;
13210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13224482741eSBarry Smith   PetscValidIntPointer(lits,2);
1323c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
13243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1325c96a6f78SLois Curfman McInnes }
1326c96a6f78SLois Curfman McInnes 
1327971e163fSPeter Brune #undef __FUNCT__
1328971e163fSPeter Brune #define __FUNCT__ "SNESSetCountersReset"
1329971e163fSPeter Brune /*@
1330971e163fSPeter Brune    SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations
1331971e163fSPeter Brune    are reset every time SNESSolve() is called.
1332971e163fSPeter Brune 
1333971e163fSPeter Brune    Logically Collective on SNES
1334971e163fSPeter Brune 
1335971e163fSPeter Brune    Input Parameter:
1336971e163fSPeter Brune +  snes - SNES context
1337971e163fSPeter Brune -  reset - whether to reset the counters or not
1338971e163fSPeter Brune 
1339971e163fSPeter Brune    Notes:
1340971e163fSPeter Brune    This is automatically called with FALSE
1341971e163fSPeter Brune 
1342971e163fSPeter Brune    Level: developer
1343971e163fSPeter Brune 
1344971e163fSPeter Brune .keywords: SNES, nonlinear, set, reset, number, linear, iterations
1345971e163fSPeter Brune 
1346be95d8f1SBarry Smith .seealso:  SNESGetNumberFunctionEvals(), SNESGetNumberLinearSolveIterations(), SNESGetNPC()
1347971e163fSPeter Brune @*/
1348971e163fSPeter Brune PetscErrorCode  SNESSetCountersReset(SNES snes,PetscBool reset)
1349971e163fSPeter Brune {
1350971e163fSPeter Brune   PetscFunctionBegin;
1351971e163fSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1352971e163fSPeter Brune   PetscValidLogicalCollectiveBool(snes,reset,2);
1353971e163fSPeter Brune   snes->counters_reset = reset;
1354971e163fSPeter Brune   PetscFunctionReturn(0);
1355971e163fSPeter Brune }
1356971e163fSPeter Brune 
135782bf6240SBarry Smith 
13584a2ae208SSatish Balay #undef __FUNCT__
13592999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
13602999313aSBarry Smith /*@
13612999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
13622999313aSBarry Smith 
13632999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
13642999313aSBarry Smith 
13652999313aSBarry Smith    Input Parameters:
13662999313aSBarry Smith +  snes - the SNES context
13672999313aSBarry Smith -  ksp - the KSP context
13682999313aSBarry Smith 
13692999313aSBarry Smith    Notes:
13702999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
13712999313aSBarry Smith    so this routine is rarely needed.
13722999313aSBarry Smith 
13732999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
13742999313aSBarry Smith    decreased by one.
13752999313aSBarry Smith 
13762999313aSBarry Smith    Level: developer
13772999313aSBarry Smith 
13782999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
13792999313aSBarry Smith 
13802999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
13812999313aSBarry Smith @*/
13827087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
13832999313aSBarry Smith {
13842999313aSBarry Smith   PetscErrorCode ierr;
13852999313aSBarry Smith 
13862999313aSBarry Smith   PetscFunctionBegin;
13870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13880700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
13892999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
13907dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1391906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
13922999313aSBarry Smith   snes->ksp = ksp;
13932999313aSBarry Smith   PetscFunctionReturn(0);
13942999313aSBarry Smith }
13952999313aSBarry Smith 
13969b94acceSBarry Smith /* -----------------------------------------------------------*/
13974a2ae208SSatish Balay #undef __FUNCT__
13984a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
139952baeb72SSatish Balay /*@
14009b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
14019b94acceSBarry Smith 
1402c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1403c7afd0dbSLois Curfman McInnes 
1404c7afd0dbSLois Curfman McInnes    Input Parameters:
1405906ed7ccSBarry Smith .  comm - MPI communicator
14069b94acceSBarry Smith 
14079b94acceSBarry Smith    Output Parameter:
14089b94acceSBarry Smith .  outsnes - the new SNES context
14099b94acceSBarry Smith 
1410c7afd0dbSLois Curfman McInnes    Options Database Keys:
1411c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1412c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1413c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1414c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1415c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1416c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1417c1f60f51SBarry Smith 
141836851e7fSLois Curfman McInnes    Level: beginner
141936851e7fSLois Curfman McInnes 
14209b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
14219b94acceSBarry Smith 
1422a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1423a8054027SBarry Smith 
14249b94acceSBarry Smith @*/
14257087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
14269b94acceSBarry Smith {
1427dfbe8321SBarry Smith   PetscErrorCode ierr;
14289b94acceSBarry Smith   SNES           snes;
1429fa9f3622SBarry Smith   SNESKSPEW      *kctx;
143037fcc0dbSBarry Smith 
14313a40ed3dSBarry Smith   PetscFunctionBegin;
1432ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
14330298fd71SBarry Smith   *outsnes = NULL;
1434607a6623SBarry Smith   ierr = SNESInitializePackage();CHKERRQ(ierr);
14358ba1e511SMatthew Knepley 
143667c2884eSBarry Smith   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
14377adad957SLisandro Dalcin 
14388d359177SBarry Smith   snes->ops->converged    = SNESConvergedDefault;
14392c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
144088976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
14419b94acceSBarry Smith   snes->max_its           = 50;
14429750a799SBarry Smith   snes->max_funcs         = 10000;
14439b94acceSBarry Smith   snes->norm              = 0.0;
1444365a6726SPeter Brune   snes->normschedule      = SNES_NORM_ALWAYS;
14456c67d002SPeter Brune   snes->functype          = SNES_FUNCTION_DEFAULT;
14463a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
14473a2046daSBarry Smith   snes->rtol              = 1.e-5;
14483a2046daSBarry Smith #else
1449b4874afaSBarry Smith   snes->rtol              = 1.e-8;
14503a2046daSBarry Smith #endif
1451b4874afaSBarry Smith   snes->ttol              = 0.0;
14523a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
14533a2046daSBarry Smith   snes->abstol            = 1.e-25;
14543a2046daSBarry Smith #else
145570441072SBarry Smith   snes->abstol            = 1.e-50;
14563a2046daSBarry Smith #endif
1457c60f73f4SPeter Brune   snes->stol              = 1.e-8;
14583a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE)
14593a2046daSBarry Smith   snes->deltatol          = 1.e-6;
14603a2046daSBarry Smith #else
14614b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
14623a2046daSBarry Smith #endif
14639b94acceSBarry Smith   snes->nfuncs            = 0;
146450ffb88aSMatthew Knepley   snes->numFailures       = 0;
146550ffb88aSMatthew Knepley   snes->maxFailures       = 1;
14667a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1467e35cf81dSBarry Smith   snes->lagjacobian       = 1;
146837ec4e1aSPeter Brune   snes->jac_iter          = 0;
146937ec4e1aSPeter Brune   snes->lagjac_persist    = PETSC_FALSE;
1470a8054027SBarry Smith   snes->lagpreconditioner = 1;
147137ec4e1aSPeter Brune   snes->pre_iter          = 0;
147237ec4e1aSPeter Brune   snes->lagpre_persist    = PETSC_FALSE;
1473639f9d9dSBarry Smith   snes->numbermonitors    = 0;
14749b94acceSBarry Smith   snes->data              = 0;
14754dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1476186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
14776f24a144SLois Curfman McInnes   snes->nwork             = 0;
147858c9b817SLisandro Dalcin   snes->work              = 0;
147958c9b817SLisandro Dalcin   snes->nvwork            = 0;
148058c9b817SLisandro Dalcin   snes->vwork             = 0;
1481758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1482758f92a0SBarry Smith   snes->conv_hist_max     = 0;
14830298fd71SBarry Smith   snes->conv_hist         = NULL;
14840298fd71SBarry Smith   snes->conv_hist_its     = NULL;
1485758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1486971e163fSPeter Brune   snes->counters_reset    = PETSC_TRUE;
1487e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1488184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
1489c40d0f55SPeter Brune   snes->pcside            = PC_RIGHT;
1490c40d0f55SPeter Brune 
1491d8f46077SPeter Brune   snes->mf          = PETSC_FALSE;
1492d8f46077SPeter Brune   snes->mf_operator = PETSC_FALSE;
1493d8f46077SPeter Brune   snes->mf_version  = 1;
1494d8f46077SPeter Brune 
14953d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
14963d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
14973d4c4710SBarry Smith 
14989b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1499b00a9115SJed Brown   ierr = PetscNewLog(snes,&kctx);CHKERRQ(ierr);
1500f5af7f23SKarl Rupp 
15019b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
15029b94acceSBarry Smith   kctx->version     = 2;
15039b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
15049b94acceSBarry Smith                              this was too large for some test cases */
150575567043SBarry Smith   kctx->rtol_last   = 0.0;
15069b94acceSBarry Smith   kctx->rtol_max    = .9;
15079b94acceSBarry Smith   kctx->gamma       = 1.0;
150862d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
150971f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
15109b94acceSBarry Smith   kctx->threshold   = .1;
151175567043SBarry Smith   kctx->lresid_last = 0.0;
151275567043SBarry Smith   kctx->norm_last   = 0.0;
15139b94acceSBarry Smith 
15149b94acceSBarry Smith   *outsnes = snes;
15153a40ed3dSBarry Smith   PetscFunctionReturn(0);
15169b94acceSBarry Smith }
15179b94acceSBarry Smith 
151888f0584fSBarry Smith /*MC
1519411c0326SBarry Smith     SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES
152088f0584fSBarry Smith 
152188f0584fSBarry Smith      Synopsis:
1522411c0326SBarry Smith      #include "petscsnes.h"
1523411c0326SBarry Smith      PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx);
152488f0584fSBarry Smith 
152588f0584fSBarry Smith      Input Parameters:
152688f0584fSBarry Smith +     snes - the SNES context
152788f0584fSBarry Smith .     x    - state at which to evaluate residual
152888f0584fSBarry Smith -     ctx     - optional user-defined function context, passed in with SNESSetFunction()
152988f0584fSBarry Smith 
153088f0584fSBarry Smith      Output Parameter:
153188f0584fSBarry Smith .     f  - vector to put residual (function value)
153288f0584fSBarry Smith 
1533878cb397SSatish Balay    Level: intermediate
1534878cb397SSatish Balay 
153588f0584fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction()
153688f0584fSBarry Smith M*/
153788f0584fSBarry Smith 
15384a2ae208SSatish Balay #undef __FUNCT__
15394a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
15409b94acceSBarry Smith /*@C
15419b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
15429b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
15439b94acceSBarry Smith    equations.
15449b94acceSBarry Smith 
15453f9fe445SBarry Smith    Logically Collective on SNES
1546fee21e36SBarry Smith 
1547c7afd0dbSLois Curfman McInnes    Input Parameters:
1548c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1549c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1550f8b49ee9SBarry Smith .  f - function evaluation routine; see SNESFunction for calling sequence details
1551c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
15520298fd71SBarry Smith          function evaluation routine (may be NULL)
15539b94acceSBarry Smith 
15549b94acceSBarry Smith    Notes:
15559b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
15569b94acceSBarry Smith $      f'(x) x = -f(x),
1557c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
15589b94acceSBarry Smith 
155936851e7fSLois Curfman McInnes    Level: beginner
156036851e7fSLois Curfman McInnes 
15619b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
15629b94acceSBarry Smith 
1563bf388a1fSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard(), SNESFunction
15649b94acceSBarry Smith @*/
1565f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
15669b94acceSBarry Smith {
156785385478SLisandro Dalcin   PetscErrorCode ierr;
15686cab3a1bSJed Brown   DM             dm;
15696cab3a1bSJed Brown 
15703a40ed3dSBarry Smith   PetscFunctionBegin;
15710700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1572d2a683ecSLisandro Dalcin   if (r) {
1573d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1574d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
157585385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
15766bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
1577f5af7f23SKarl Rupp 
157885385478SLisandro Dalcin     snes->vec_func = r;
1579d2a683ecSLisandro Dalcin   }
15806cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1581f8b49ee9SBarry Smith   ierr = DMSNESSetFunction(dm,f,ctx);CHKERRQ(ierr);
15823a40ed3dSBarry Smith   PetscFunctionReturn(0);
15839b94acceSBarry Smith }
15849b94acceSBarry Smith 
1585646217ecSPeter Brune 
1586646217ecSPeter Brune #undef __FUNCT__
1587e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1588e4ed7901SPeter Brune /*@C
1589e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1590e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1591e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1592e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1593e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1594e4ed7901SPeter Brune 
1595e4ed7901SPeter Brune    Logically Collective on SNES
1596e4ed7901SPeter Brune 
1597e4ed7901SPeter Brune    Input Parameters:
1598e4ed7901SPeter Brune +  snes - the SNES context
1599e4ed7901SPeter Brune -  f - vector to store function value
1600e4ed7901SPeter Brune 
1601e4ed7901SPeter Brune    Notes:
1602e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1603e4ed7901SPeter Brune 
1604e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1605e4ed7901SPeter Brune 
1606e4ed7901SPeter Brune    Level: developer
1607e4ed7901SPeter Brune 
1608e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1609e4ed7901SPeter Brune 
1610e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1611e4ed7901SPeter Brune @*/
1612e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1613e4ed7901SPeter Brune {
1614e4ed7901SPeter Brune   PetscErrorCode ierr;
1615e4ed7901SPeter Brune   Vec            vec_func;
1616e4ed7901SPeter Brune 
1617e4ed7901SPeter Brune   PetscFunctionBegin;
1618e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1619e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1620e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
16215c9e203fSPeter Brune   if (snes->pcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) {
1622902f982fSPeter Brune     snes->vec_func_init_set = PETSC_FALSE;
1623902f982fSPeter Brune     PetscFunctionReturn(0);
1624902f982fSPeter Brune   }
16250298fd71SBarry Smith   ierr = SNESGetFunction(snes,&vec_func,NULL,NULL);CHKERRQ(ierr);
1626e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1627f5af7f23SKarl Rupp 
1628217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1629e4ed7901SPeter Brune   PetscFunctionReturn(0);
1630e4ed7901SPeter Brune }
1631e4ed7901SPeter Brune 
1632e4ed7901SPeter Brune #undef __FUNCT__
1633365a6726SPeter Brune #define __FUNCT__ "SNESSetNormSchedule"
1634534ebe21SPeter Brune /*@
1635365a6726SPeter Brune    SNESSetNormSchedule - Sets the SNESNormSchedule used in covergence and monitoring
1636534ebe21SPeter Brune    of the SNES method.
1637534ebe21SPeter Brune 
1638534ebe21SPeter Brune    Logically Collective on SNES
1639534ebe21SPeter Brune 
1640534ebe21SPeter Brune    Input Parameters:
1641534ebe21SPeter Brune +  snes - the SNES context
1642365a6726SPeter Brune -  normschedule - the frequency of norm computation
1643534ebe21SPeter Brune 
1644517f1916SMatthew G. Knepley    Options Database Key:
1645517f1916SMatthew G. Knepley .  -snes_norm_schedule <none, always, initialonly, finalonly, initalfinalonly>
1646517f1916SMatthew G. Knepley 
1647534ebe21SPeter Brune    Notes:
1648365a6726SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
1649534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1650534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1651be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
1652534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1653534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1654534ebe21SPeter Brune    their solution.
1655534ebe21SPeter Brune 
1656534ebe21SPeter Brune    Level: developer
1657534ebe21SPeter Brune 
1658534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1659534ebe21SPeter Brune 
1660365a6726SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1661534ebe21SPeter Brune @*/
1662365a6726SPeter Brune PetscErrorCode  SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule)
1663534ebe21SPeter Brune {
1664534ebe21SPeter Brune   PetscFunctionBegin;
1665534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1666365a6726SPeter Brune   snes->normschedule = normschedule;
1667534ebe21SPeter Brune   PetscFunctionReturn(0);
1668534ebe21SPeter Brune }
1669534ebe21SPeter Brune 
1670534ebe21SPeter Brune 
1671534ebe21SPeter Brune #undef __FUNCT__
1672365a6726SPeter Brune #define __FUNCT__ "SNESGetNormSchedule"
1673534ebe21SPeter Brune /*@
1674365a6726SPeter Brune    SNESGetNormSchedule - Gets the SNESNormSchedule used in covergence and monitoring
1675534ebe21SPeter Brune    of the SNES method.
1676534ebe21SPeter Brune 
1677534ebe21SPeter Brune    Logically Collective on SNES
1678534ebe21SPeter Brune 
1679534ebe21SPeter Brune    Input Parameters:
1680534ebe21SPeter Brune +  snes - the SNES context
1681365a6726SPeter Brune -  normschedule - the type of the norm used
1682534ebe21SPeter Brune 
1683534ebe21SPeter Brune    Level: advanced
1684534ebe21SPeter Brune 
1685534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1686534ebe21SPeter Brune 
1687365a6726SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
1688534ebe21SPeter Brune @*/
1689365a6726SPeter Brune PetscErrorCode  SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule)
1690534ebe21SPeter Brune {
1691534ebe21SPeter Brune   PetscFunctionBegin;
1692534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1693365a6726SPeter Brune   *normschedule = snes->normschedule;
1694534ebe21SPeter Brune   PetscFunctionReturn(0);
1695534ebe21SPeter Brune }
1696534ebe21SPeter Brune 
169747073ea2SPeter Brune 
169847073ea2SPeter Brune #undef __FUNCT__
169947073ea2SPeter Brune #define __FUNCT__ "SNESSetFunctionType"
170047073ea2SPeter Brune /*@C
170147073ea2SPeter Brune    SNESSetFunctionType - Sets the SNESNormSchedule used in covergence and monitoring
170247073ea2SPeter Brune    of the SNES method.
170347073ea2SPeter Brune 
170447073ea2SPeter Brune    Logically Collective on SNES
170547073ea2SPeter Brune 
170647073ea2SPeter Brune    Input Parameters:
170747073ea2SPeter Brune +  snes - the SNES context
170847073ea2SPeter Brune -  normschedule - the frequency of norm computation
170947073ea2SPeter Brune 
171047073ea2SPeter Brune    Notes:
171147073ea2SPeter Brune    Only certain SNES methods support certain SNESNormSchedules.  Most require evaluation
171247073ea2SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
171347073ea2SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1714be95d8f1SBarry Smith    (SNESNGS) and the like do not require the norm of the function to be computed, and therfore
171547073ea2SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
171647073ea2SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
171747073ea2SPeter Brune    their solution.
171847073ea2SPeter Brune 
171947073ea2SPeter Brune    Level: developer
172047073ea2SPeter Brune 
172147073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
172247073ea2SPeter Brune 
172347073ea2SPeter Brune .seealso: SNESGetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
172447073ea2SPeter Brune @*/
172547073ea2SPeter Brune PetscErrorCode  SNESSetFunctionType(SNES snes, SNESFunctionType type)
172647073ea2SPeter Brune {
172747073ea2SPeter Brune   PetscFunctionBegin;
172847073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
172947073ea2SPeter Brune   snes->functype = type;
173047073ea2SPeter Brune   PetscFunctionReturn(0);
173147073ea2SPeter Brune }
173247073ea2SPeter Brune 
173347073ea2SPeter Brune 
173447073ea2SPeter Brune #undef __FUNCT__
173547073ea2SPeter Brune #define __FUNCT__ "SNESGetFunctionType"
173647073ea2SPeter Brune /*@C
173747073ea2SPeter Brune    SNESGetFunctionType - Gets the SNESNormSchedule used in covergence and monitoring
173847073ea2SPeter Brune    of the SNES method.
173947073ea2SPeter Brune 
174047073ea2SPeter Brune    Logically Collective on SNES
174147073ea2SPeter Brune 
174247073ea2SPeter Brune    Input Parameters:
174347073ea2SPeter Brune +  snes - the SNES context
174447073ea2SPeter Brune -  normschedule - the type of the norm used
174547073ea2SPeter Brune 
174647073ea2SPeter Brune    Level: advanced
174747073ea2SPeter Brune 
174847073ea2SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
174947073ea2SPeter Brune 
175047073ea2SPeter Brune .seealso: SNESSetNormSchedule(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormSchedule
175147073ea2SPeter Brune @*/
175247073ea2SPeter Brune PetscErrorCode  SNESGetFunctionType(SNES snes, SNESFunctionType *type)
175347073ea2SPeter Brune {
175447073ea2SPeter Brune   PetscFunctionBegin;
175547073ea2SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
175647073ea2SPeter Brune   *type = snes->functype;
1757534ebe21SPeter Brune   PetscFunctionReturn(0);
1758534ebe21SPeter Brune }
1759534ebe21SPeter Brune 
1760bf388a1fSBarry Smith /*MC
1761be95d8f1SBarry Smith     SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function
1762bf388a1fSBarry Smith 
1763bf388a1fSBarry Smith      Synopsis:
1764aaa7dc30SBarry Smith      #include <petscsnes.h>
1765be95d8f1SBarry Smith $    SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx);
1766bf388a1fSBarry Smith 
1767bf388a1fSBarry Smith +  X   - solution vector
1768bf388a1fSBarry Smith .  B   - RHS vector
1769bf388a1fSBarry Smith -  ctx - optional user-defined Gauss-Seidel context
1770bf388a1fSBarry Smith 
1771878cb397SSatish Balay    Level: intermediate
1772878cb397SSatish Balay 
1773be95d8f1SBarry Smith .seealso:   SNESSetNGS(), SNESGetNGS()
1774bf388a1fSBarry Smith M*/
1775bf388a1fSBarry Smith 
1776534ebe21SPeter Brune #undef __FUNCT__
1777be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNGS"
1778c79ef259SPeter Brune /*@C
1779be95d8f1SBarry Smith    SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for
1780c79ef259SPeter Brune    use with composed nonlinear solvers.
1781c79ef259SPeter Brune 
1782c79ef259SPeter Brune    Input Parameters:
1783c79ef259SPeter Brune +  snes   - the SNES context
1784be95d8f1SBarry Smith .  f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction
1785c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
17860298fd71SBarry Smith             smoother evaluation routine (may be NULL)
1787c79ef259SPeter Brune 
1788c79ef259SPeter Brune    Notes:
1789be95d8f1SBarry Smith    The NGS routines are used by the composed nonlinear solver to generate
1790c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1791c79ef259SPeter Brune 
1792d28543b3SPeter Brune    Level: intermediate
1793c79ef259SPeter Brune 
1794d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1795c79ef259SPeter Brune 
1796be95d8f1SBarry Smith .seealso: SNESGetFunction(), SNESComputeNGS()
1797c79ef259SPeter Brune @*/
1798be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx)
17996cab3a1bSJed Brown {
18006cab3a1bSJed Brown   PetscErrorCode ierr;
18016cab3a1bSJed Brown   DM             dm;
18026cab3a1bSJed Brown 
1803646217ecSPeter Brune   PetscFunctionBegin;
18046cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18056cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1806be95d8f1SBarry Smith   ierr = DMSNESSetNGS(dm,f,ctx);CHKERRQ(ierr);
1807646217ecSPeter Brune   PetscFunctionReturn(0);
1808646217ecSPeter Brune }
1809646217ecSPeter Brune 
1810d25893d9SBarry Smith #undef __FUNCT__
18118b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
181282b59a81SJed Brown PETSC_EXTERN PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
18138b0a5094SBarry Smith {
18148b0a5094SBarry Smith   PetscErrorCode ierr;
1815e03ab78fSPeter Brune   DM             dm;
1816942e3340SBarry Smith   DMSNES         sdm;
18176cab3a1bSJed Brown 
18188b0a5094SBarry Smith   PetscFunctionBegin;
1819e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1820942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
18218b0a5094SBarry Smith   /*  A(x)*x - b(x) */
182222c6f798SBarry Smith   if (sdm->ops->computepfunction) {
182322c6f798SBarry Smith     ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
182422c6f798SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
1825e03ab78fSPeter Brune 
182622c6f798SBarry Smith   if (sdm->ops->computepjacobian) {
1827d1e9a80fSBarry Smith     ierr = (*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx);CHKERRQ(ierr);
182874e1e8c1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
18298b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
183095eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
18318b0a5094SBarry Smith   PetscFunctionReturn(0);
18328b0a5094SBarry Smith }
18338b0a5094SBarry Smith 
18348b0a5094SBarry Smith #undef __FUNCT__
18358b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
1836d1e9a80fSBarry Smith PETSC_EXTERN PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx)
18378b0a5094SBarry Smith {
18388b0a5094SBarry Smith   PetscFunctionBegin;
1839e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
18408b0a5094SBarry Smith   PetscFunctionReturn(0);
18418b0a5094SBarry Smith }
18428b0a5094SBarry Smith 
18438b0a5094SBarry Smith #undef __FUNCT__
18448b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
18458b0a5094SBarry Smith /*@C
18460d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
18478b0a5094SBarry Smith 
18488b0a5094SBarry Smith    Logically Collective on SNES
18498b0a5094SBarry Smith 
18508b0a5094SBarry Smith    Input Parameters:
18518b0a5094SBarry Smith +  snes - the SNES context
18528b0a5094SBarry Smith .  r - vector to store function value
1853f8b49ee9SBarry Smith .  b - function evaluation routine
1854e5d3d808SBarry Smith .  Amat - matrix with which A(x) x - b(x) is to be computed
1855e5d3d808SBarry Smith .  Pmat - matrix from which preconditioner is computed (usually the same as Amat)
1856411c0326SBarry Smith .  J  - function to compute matrix value, see SNESJacobianFunction for details on its calling sequence
18578b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
18580298fd71SBarry Smith          function evaluation routine (may be NULL)
18598b0a5094SBarry Smith 
18608b0a5094SBarry Smith    Notes:
1861f450aa47SBarry 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
1862f450aa47SBarry 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.
1863f450aa47SBarry Smith 
18648b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
18658b0a5094SBarry Smith 
18668b0a5094SBarry 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}
18678b0a5094SBarry 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.
18688b0a5094SBarry Smith 
18698b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
18708b0a5094SBarry Smith 
18710d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
18720d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
18738b0a5094SBarry Smith 
18748b0a5094SBarry 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
18758b0a5094SBarry 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
18768b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
18778b0a5094SBarry Smith 
1878f450aa47SBarry Smith    Level: intermediate
18798b0a5094SBarry Smith 
18808b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
18818b0a5094SBarry Smith 
1882411c0326SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard(), SNESJacobianFunction
18838b0a5094SBarry Smith @*/
1884d1e9a80fSBarry 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)
18858b0a5094SBarry Smith {
18868b0a5094SBarry Smith   PetscErrorCode ierr;
1887e03ab78fSPeter Brune   DM             dm;
1888e03ab78fSPeter Brune 
18898b0a5094SBarry Smith   PetscFunctionBegin;
18908b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1891e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1892f8b49ee9SBarry Smith   ierr = DMSNESSetPicard(dm,b,J,ctx);CHKERRQ(ierr);
18938b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
1894e5d3d808SBarry Smith   ierr = SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
18958b0a5094SBarry Smith   PetscFunctionReturn(0);
18968b0a5094SBarry Smith }
18978b0a5094SBarry Smith 
18987971a8bfSPeter Brune #undef __FUNCT__
18997971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard"
19007971a8bfSPeter Brune /*@C
19017971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
19027971a8bfSPeter Brune 
19037971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
19047971a8bfSPeter Brune 
19057971a8bfSPeter Brune    Input Parameter:
19067971a8bfSPeter Brune .  snes - the SNES context
19077971a8bfSPeter Brune 
19087971a8bfSPeter Brune    Output Parameter:
19090298fd71SBarry Smith +  r - the function (or NULL)
1910f8b49ee9SBarry Smith .  f - the function (or NULL); see SNESFunction for calling sequence details
1911e4357dc4SBarry Smith .  Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL)
1912e4357dc4SBarry Smith .  Pmat  - the matrix from which the preconditioner will be constructed (or NULL)
1913f8b49ee9SBarry Smith .  J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details
19140298fd71SBarry Smith -  ctx - the function context (or NULL)
19157971a8bfSPeter Brune 
19167971a8bfSPeter Brune    Level: advanced
19177971a8bfSPeter Brune 
19187971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
19197971a8bfSPeter Brune 
1920e4357dc4SBarry Smith .seealso: SNESSetPicard(), SNESGetFunction(), SNESGetJacobian(), SNESGetDM(), SNESFunction, SNESJacobianFunction
19217971a8bfSPeter Brune @*/
1922d1e9a80fSBarry 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)
19237971a8bfSPeter Brune {
19247971a8bfSPeter Brune   PetscErrorCode ierr;
19257971a8bfSPeter Brune   DM             dm;
19267971a8bfSPeter Brune 
19277971a8bfSPeter Brune   PetscFunctionBegin;
19287971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19290298fd71SBarry Smith   ierr = SNESGetFunction(snes,r,NULL,NULL);CHKERRQ(ierr);
1930e4357dc4SBarry Smith   ierr = SNESGetJacobian(snes,Amat,Pmat,NULL,NULL);CHKERRQ(ierr);
19317971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1932f8b49ee9SBarry Smith   ierr = DMSNESGetPicard(dm,f,J,ctx);CHKERRQ(ierr);
19337971a8bfSPeter Brune   PetscFunctionReturn(0);
19347971a8bfSPeter Brune }
19357971a8bfSPeter Brune 
19368b0a5094SBarry Smith #undef __FUNCT__
1937d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1938d25893d9SBarry Smith /*@C
1939d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1940d25893d9SBarry Smith 
1941d25893d9SBarry Smith    Logically Collective on SNES
1942d25893d9SBarry Smith 
1943d25893d9SBarry Smith    Input Parameters:
1944d25893d9SBarry Smith +  snes - the SNES context
1945d25893d9SBarry Smith .  func - function evaluation routine
1946d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
19470298fd71SBarry Smith          function evaluation routine (may be NULL)
1948d25893d9SBarry Smith 
1949d25893d9SBarry Smith    Calling sequence of func:
1950d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1951d25893d9SBarry Smith 
1952d25893d9SBarry Smith .  f - function vector
1953d25893d9SBarry Smith -  ctx - optional user-defined function context
1954d25893d9SBarry Smith 
1955d25893d9SBarry Smith    Level: intermediate
1956d25893d9SBarry Smith 
1957d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1958d25893d9SBarry Smith 
1959d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1960d25893d9SBarry Smith @*/
1961d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1962d25893d9SBarry Smith {
1963d25893d9SBarry Smith   PetscFunctionBegin;
1964d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1965d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1966d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1967d25893d9SBarry Smith   PetscFunctionReturn(0);
1968d25893d9SBarry Smith }
1969d25893d9SBarry Smith 
19703ab0aad5SBarry Smith /* --------------------------------------------------------------- */
19713ab0aad5SBarry Smith #undef __FUNCT__
19721096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
19731096aae1SMatthew Knepley /*@C
19741096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
19751096aae1SMatthew Knepley    it assumes a zero right hand side.
19761096aae1SMatthew Knepley 
19773f9fe445SBarry Smith    Logically Collective on SNES
19781096aae1SMatthew Knepley 
19791096aae1SMatthew Knepley    Input Parameter:
19801096aae1SMatthew Knepley .  snes - the SNES context
19811096aae1SMatthew Knepley 
19821096aae1SMatthew Knepley    Output Parameter:
19830298fd71SBarry Smith .  rhs - the right hand side vector or NULL if the right hand side vector is null
19841096aae1SMatthew Knepley 
19851096aae1SMatthew Knepley    Level: intermediate
19861096aae1SMatthew Knepley 
19871096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
19881096aae1SMatthew Knepley 
198985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
19901096aae1SMatthew Knepley @*/
19917087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
19921096aae1SMatthew Knepley {
19931096aae1SMatthew Knepley   PetscFunctionBegin;
19940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19951096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
199685385478SLisandro Dalcin   *rhs = snes->vec_rhs;
19971096aae1SMatthew Knepley   PetscFunctionReturn(0);
19981096aae1SMatthew Knepley }
19991096aae1SMatthew Knepley 
20001096aae1SMatthew Knepley #undef __FUNCT__
20014a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
20029b94acceSBarry Smith /*@
2003bf388a1fSBarry Smith    SNESComputeFunction - Calls the function that has been set with SNESSetFunction().
20049b94acceSBarry Smith 
2005c7afd0dbSLois Curfman McInnes    Collective on SNES
2006c7afd0dbSLois Curfman McInnes 
20079b94acceSBarry Smith    Input Parameters:
2008c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2009c7afd0dbSLois Curfman McInnes -  x - input vector
20109b94acceSBarry Smith 
20119b94acceSBarry Smith    Output Parameter:
20123638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
20139b94acceSBarry Smith 
20141bffabb2SLois Curfman McInnes    Notes:
201536851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
201636851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
201736851e7fSLois Curfman McInnes    themselves.
201836851e7fSLois Curfman McInnes 
201936851e7fSLois Curfman McInnes    Level: developer
202036851e7fSLois Curfman McInnes 
20219b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
20229b94acceSBarry Smith 
2023a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
20249b94acceSBarry Smith @*/
20257087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
20269b94acceSBarry Smith {
2027dfbe8321SBarry Smith   PetscErrorCode ierr;
20286cab3a1bSJed Brown   DM             dm;
2029942e3340SBarry Smith   DMSNES         sdm;
20309b94acceSBarry Smith 
20313a40ed3dSBarry Smith   PetscFunctionBegin;
20320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20330700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
20340700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2035c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2036c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
203762796dfbSBarry Smith   ierr = VecValidValues(x,2,PETSC_TRUE);CHKERRQ(ierr);
2038184914b5SBarry Smith 
20396cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2040942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
204132f3f7c2SPeter Brune   if (sdm->ops->computefunction) {
2042ccf3c845SPeter Brune     ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
20435edff71fSBarry Smith     ierr = VecLockPush(x);CHKERRQ(ierr);
2044d64ed03dSBarry Smith     PetscStackPush("SNES user function");
204522c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2046d64ed03dSBarry Smith     PetscStackPop;
20475edff71fSBarry Smith     ierr = VecLockPop(x);CHKERRQ(ierr);
2048ccf3c845SPeter Brune     ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
2049c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2050c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2051644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
205285385478SLisandro Dalcin   if (snes->vec_rhs) {
205385385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
20543ab0aad5SBarry Smith   }
2055ae3c334cSLois Curfman McInnes   snes->nfuncs++;
205662796dfbSBarry Smith   ierr = VecValidValues(y,3,PETSC_FALSE);CHKERRQ(ierr);
20573a40ed3dSBarry Smith   PetscFunctionReturn(0);
20589b94acceSBarry Smith }
20599b94acceSBarry Smith 
20604a2ae208SSatish Balay #undef __FUNCT__
2061be95d8f1SBarry Smith #define __FUNCT__ "SNESComputeNGS"
2062c79ef259SPeter Brune /*@
2063be95d8f1SBarry Smith    SNESComputeNGS - Calls the Gauss-Seidel function that has been set with  SNESSetNGS().
2064c79ef259SPeter Brune 
2065c79ef259SPeter Brune    Collective on SNES
2066c79ef259SPeter Brune 
2067c79ef259SPeter Brune    Input Parameters:
2068c79ef259SPeter Brune +  snes - the SNES context
2069c79ef259SPeter Brune .  x - input vector
2070c79ef259SPeter Brune -  b - rhs vector
2071c79ef259SPeter Brune 
2072c79ef259SPeter Brune    Output Parameter:
2073c79ef259SPeter Brune .  x - new solution vector
2074c79ef259SPeter Brune 
2075c79ef259SPeter Brune    Notes:
2076be95d8f1SBarry Smith    SNESComputeNGS() is typically used within composed nonlinear solver
2077c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2078c79ef259SPeter Brune    themselves.
2079c79ef259SPeter Brune 
2080c79ef259SPeter Brune    Level: developer
2081c79ef259SPeter Brune 
2082c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
2083c79ef259SPeter Brune 
2084be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESComputeFunction()
2085c79ef259SPeter Brune @*/
2086be95d8f1SBarry Smith PetscErrorCode  SNESComputeNGS(SNES snes,Vec b,Vec x)
2087646217ecSPeter Brune {
2088646217ecSPeter Brune   PetscErrorCode ierr;
20896cab3a1bSJed Brown   DM             dm;
2090942e3340SBarry Smith   DMSNES         sdm;
2091646217ecSPeter Brune 
2092646217ecSPeter Brune   PetscFunctionBegin;
2093646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2094646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2095646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2096646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2097646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
209862796dfbSBarry Smith   if (b) {ierr = VecValidValues(b,2,PETSC_TRUE);CHKERRQ(ierr);}
2099be95d8f1SBarry Smith   ierr = PetscLogEventBegin(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
21006cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2101942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
210222c6f798SBarry Smith   if (sdm->ops->computegs) {
21035edff71fSBarry Smith     if (b) {ierr = VecLockPush(b);CHKERRQ(ierr);}
2104be95d8f1SBarry Smith     PetscStackPush("SNES user NGS");
210522c6f798SBarry Smith     ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2106646217ecSPeter Brune     PetscStackPop;
21075edff71fSBarry Smith     if (b) {ierr = VecLockPop(b);CHKERRQ(ierr);}
2108be95d8f1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve().");
2109be95d8f1SBarry Smith   ierr = PetscLogEventEnd(SNES_NGSEval,snes,x,b,0);CHKERRQ(ierr);
211062796dfbSBarry Smith   ierr = VecValidValues(x,3,PETSC_FALSE);CHKERRQ(ierr);
2111646217ecSPeter Brune   PetscFunctionReturn(0);
2112646217ecSPeter Brune }
2113646217ecSPeter Brune 
2114646217ecSPeter Brune #undef __FUNCT__
21154a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
211662fef451SLois Curfman McInnes /*@
2117bf388a1fSBarry Smith    SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian().
211862fef451SLois Curfman McInnes 
2119c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2120c7afd0dbSLois Curfman McInnes 
212162fef451SLois Curfman McInnes    Input Parameters:
2122c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2123c7afd0dbSLois Curfman McInnes -  x - input vector
212462fef451SLois Curfman McInnes 
212562fef451SLois Curfman McInnes    Output Parameters:
2126c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
2127d1e9a80fSBarry Smith -  B - optional preconditioning matrix
2128fee21e36SBarry Smith 
2129e35cf81dSBarry Smith   Options Database Keys:
2130e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2131693365a8SJed Brown .    -snes_lag_jacobian <lag>
2132693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2133693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2134693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
21354c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
2136c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
2137c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2138c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2139c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2140c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
21414c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2142c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2143c01495d3SJed Brown 
2144e35cf81dSBarry Smith 
214562fef451SLois Curfman McInnes    Notes:
214662fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
214762fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
214862fef451SLois Curfman McInnes 
214936851e7fSLois Curfman McInnes    Level: developer
215036851e7fSLois Curfman McInnes 
215162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
215262fef451SLois Curfman McInnes 
2153e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
215462fef451SLois Curfman McInnes @*/
2155d1e9a80fSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B)
21569b94acceSBarry Smith {
2157dfbe8321SBarry Smith   PetscErrorCode ierr;
2158ace3abfcSBarry Smith   PetscBool      flag;
21596cab3a1bSJed Brown   DM             dm;
2160942e3340SBarry Smith   DMSNES         sdm;
2161e0e3a89bSBarry Smith   KSP            ksp;
21623a40ed3dSBarry Smith 
21633a40ed3dSBarry Smith   PetscFunctionBegin;
21640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21650700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
2166c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
216762796dfbSBarry Smith   ierr = VecValidValues(X,2,PETSC_TRUE);CHKERRQ(ierr);
21686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2169942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
21703232da50SPeter Brune 
2171ce94432eSBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2172ebd3b9afSBarry Smith 
2173ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2174ebd3b9afSBarry Smith 
2175fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2176fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2177f5af7f23SKarl Rupp 
2178fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2179fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2180e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
218194ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2182ebd3b9afSBarry Smith     if (flag) {
218394ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
218494ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2185ebd3b9afSBarry Smith     }
2186e35cf81dSBarry Smith     PetscFunctionReturn(0);
218737ec4e1aSPeter Brune   } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) {
2188e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
218994ab13aaSBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag);CHKERRQ(ierr);
2190ebd3b9afSBarry Smith     if (flag) {
219194ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
219294ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2193ebd3b9afSBarry Smith     }
2194e35cf81dSBarry Smith     PetscFunctionReturn(0);
2195e35cf81dSBarry Smith   }
2196d728fb7dSPeter Brune   if (snes->pc && snes->pcside == PC_LEFT) {
219794ab13aaSBarry Smith       ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
219894ab13aaSBarry Smith       ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2199d728fb7dSPeter Brune       PetscFunctionReturn(0);
2200d728fb7dSPeter Brune   }
2201e35cf81dSBarry Smith 
220294ab13aaSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
22035edff71fSBarry Smith   ierr = VecLockPush(X);CHKERRQ(ierr);
2204d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
2205d1e9a80fSBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx);CHKERRQ(ierr);
2206d64ed03dSBarry Smith   PetscStackPop;
22075edff71fSBarry Smith   ierr = VecLockPop(X);CHKERRQ(ierr);
220894ab13aaSBarry Smith   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B);CHKERRQ(ierr);
2209a8054027SBarry Smith 
2210e0e3a89bSBarry Smith   /* the next line ensures that snes->ksp exists */
2211e0e3a89bSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
22123b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
22133b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
2214d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
22153b4f5425SBarry Smith     snes->lagpreconditioner = -1;
22163b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2217a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2218d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
221937ec4e1aSPeter Brune   } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) {
2220a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2221d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE);CHKERRQ(ierr);
2222d1e9a80fSBarry Smith   } else {
2223d1e9a80fSBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner\n");CHKERRQ(ierr);
2224d1e9a80fSBarry Smith     ierr = KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE);CHKERRQ(ierr);
2225a8054027SBarry Smith   }
2226a8054027SBarry Smith 
22276d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
222894ab13aaSBarry Smith   /* PetscValidHeaderSpecific(A,MAT_CLASSID,3);
222994ab13aaSBarry Smith     PetscValidHeaderSpecific(B,MAT_CLASSID,4);   */
2230693365a8SJed Brown   {
2231693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
22320298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,NULL);CHKERRQ(ierr);
22330298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,NULL);CHKERRQ(ierr);
22340298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,NULL);CHKERRQ(ierr);
22350298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,NULL);CHKERRQ(ierr);
2236693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
22370298fd71SBarry Smith       Mat          Bexp_mine = NULL,Bexp,FDexp;
2238693365a8SJed Brown       PetscViewer  vdraw,vstdout;
22396b3a5b13SJed Brown       PetscBool    flg;
2240693365a8SJed Brown       if (flag_operator) {
224194ab13aaSBarry Smith         ierr = MatComputeExplicitOperator(A,&Bexp_mine);CHKERRQ(ierr);
2242693365a8SJed Brown         Bexp = Bexp_mine;
2243693365a8SJed Brown       } else {
2244693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
224594ab13aaSBarry Smith         ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
224694ab13aaSBarry Smith         if (flg) Bexp = B;
2247693365a8SJed Brown         else {
2248693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
224994ab13aaSBarry Smith           ierr = MatComputeExplicitOperator(B,&Bexp_mine);CHKERRQ(ierr);
2250693365a8SJed Brown           Bexp = Bexp_mine;
2251693365a8SJed Brown         }
2252693365a8SJed Brown       }
2253693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2254d1e9a80fSBarry Smith       ierr = SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL);CHKERRQ(ierr);
2255ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
2256693365a8SJed Brown       if (flag_draw || flag_contour) {
2257ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2258693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
22590298fd71SBarry Smith       } else vdraw = NULL;
2260693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian");CHKERRQ(ierr);
2261693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2262693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2263693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2264693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2265693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2266693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2267693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2268693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2269693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2270693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2271693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2272693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2273693365a8SJed Brown       }
2274693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2275693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2276693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2277693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2278693365a8SJed Brown     }
2279693365a8SJed Brown   }
22804c30e9fbSJed Brown   {
22816719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
22826719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
22830298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,NULL);CHKERRQ(ierr);
22840298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,NULL);CHKERRQ(ierr);
22850298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,NULL);CHKERRQ(ierr);
22860298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,NULL);CHKERRQ(ierr);
22870298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,NULL);CHKERRQ(ierr);
22880298fd71SBarry Smith     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL);CHKERRQ(ierr);
22890298fd71SBarry Smith     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL);CHKERRQ(ierr);
22906719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
22914c30e9fbSJed Brown       Mat            Bfd;
22924c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
2293335efc43SPeter Brune       MatColoring    coloring;
22944c30e9fbSJed Brown       ISColoring     iscoloring;
22954c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
22964c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
22974c30e9fbSJed Brown       void           *funcctx;
22986719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
22994c30e9fbSJed Brown 
230094ab13aaSBarry Smith       ierr = MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
2301335efc43SPeter Brune       ierr = MatColoringCreate(Bfd,&coloring);CHKERRQ(ierr);
2302335efc43SPeter Brune       ierr = MatColoringSetType(coloring,MATCOLORINGSL);CHKERRQ(ierr);
2303335efc43SPeter Brune       ierr = MatColoringSetFromOptions(coloring);CHKERRQ(ierr);
2304335efc43SPeter Brune       ierr = MatColoringApply(coloring,&iscoloring);CHKERRQ(ierr);
2305335efc43SPeter Brune       ierr = MatColoringDestroy(&coloring);CHKERRQ(ierr);
23064c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
2307f86b9fbaSHong Zhang       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2308f86b9fbaSHong Zhang       ierr = MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring);CHKERRQ(ierr);
23094c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
23104c30e9fbSJed Brown 
23114c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
23120298fd71SBarry Smith       ierr = SNESGetFunction(snes,NULL,&func,&funcctx);CHKERRQ(ierr);
23134c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx);CHKERRQ(ierr);
23144c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
23154c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
23164c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
2317d1e9a80fSBarry Smith       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,snes);CHKERRQ(ierr);
23184c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
23194c30e9fbSJed Brown 
2320ce94432eSBarry Smith       ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout);CHKERRQ(ierr);
23214c30e9fbSJed Brown       if (flag_draw || flag_contour) {
2322ce94432eSBarry Smith         ierr = PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
23234c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
23240298fd71SBarry Smith       } else vdraw = NULL;
23254c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
232694ab13aaSBarry Smith       if (flag_display) {ierr = MatView(B,vstdout);CHKERRQ(ierr);}
232794ab13aaSBarry Smith       if (vdraw) {ierr = MatView(B,vdraw);CHKERRQ(ierr);}
23284c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
23296719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
23304c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
233194ab13aaSBarry Smith       ierr = MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
23324c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
23336719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
23344c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
233557622a8eSBarry 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);
23366719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
23374c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
23384c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
23394c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
23404c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
23414c30e9fbSJed Brown       }
23424c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
23436719d8e4SJed Brown 
23446719d8e4SJed Brown       if (flag_threshold) {
23456719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
234694ab13aaSBarry Smith         ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
234794ab13aaSBarry Smith         ierr = MatGetOwnershipRange(B,&rstart,&rend);CHKERRQ(ierr);
23486719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
23496719d8e4SJed Brown           const PetscScalar *ba,*ca;
23506719d8e4SJed Brown           const PetscInt    *bj,*cj;
23516719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
23526719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
235394ab13aaSBarry Smith           ierr = MatGetRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
23546719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
235594ab13aaSBarry Smith           if (bn != cn) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
23566719d8e4SJed Brown           for (j=0; j<bn; j++) {
23576719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
23586719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
23596719d8e4SJed Brown               maxentrycol = bj[j];
23606719d8e4SJed Brown               maxentry    = PetscRealPart(ba[j]);
23616719d8e4SJed Brown             }
23626719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
23636719d8e4SJed Brown               maxdiffcol = bj[j];
23646719d8e4SJed Brown               maxdiff    = PetscRealPart(ca[j]);
23656719d8e4SJed Brown             }
23666719d8e4SJed Brown             if (rdiff > maxrdiff) {
23676719d8e4SJed Brown               maxrdiffcol = bj[j];
23686719d8e4SJed Brown               maxrdiff    = rdiff;
23696719d8e4SJed Brown             }
23706719d8e4SJed Brown           }
23716719d8e4SJed Brown           if (maxrdiff > 1) {
237257622a8eSBarry 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);
23736719d8e4SJed Brown             for (j=0; j<bn; j++) {
23746719d8e4SJed Brown               PetscReal rdiff;
23756719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
23766719d8e4SJed Brown               if (rdiff > 1) {
237757622a8eSBarry Smith                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]));CHKERRQ(ierr);
23786719d8e4SJed Brown               }
23796719d8e4SJed Brown             }
23806719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
23816719d8e4SJed Brown           }
238294ab13aaSBarry Smith           ierr = MatRestoreRow(B,i,&bn,&bj,&ba);CHKERRQ(ierr);
23836719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
23846719d8e4SJed Brown         }
23856719d8e4SJed Brown       }
23864c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
23874c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
23884c30e9fbSJed Brown     }
23894c30e9fbSJed Brown   }
23903a40ed3dSBarry Smith   PetscFunctionReturn(0);
23919b94acceSBarry Smith }
23929b94acceSBarry Smith 
2393bf388a1fSBarry Smith /*MC
2394411c0326SBarry Smith     SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES
2395bf388a1fSBarry Smith 
2396bf388a1fSBarry Smith      Synopsis:
2397411c0326SBarry Smith      #include "petscsnes.h"
2398411c0326SBarry Smith      PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx);
2399bf388a1fSBarry Smith 
2400bf388a1fSBarry Smith +  x - input vector
2401e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2402e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2403bf388a1fSBarry Smith -  ctx - [optional] user-defined Jacobian context
2404bf388a1fSBarry Smith 
2405878cb397SSatish Balay    Level: intermediate
2406878cb397SSatish Balay 
2407bf388a1fSBarry Smith .seealso:   SNESSetFunction(), SNESGetFunction(), SNESSetJacobian(), SNESGetJacobian()
2408bf388a1fSBarry Smith M*/
2409bf388a1fSBarry Smith 
24104a2ae208SSatish Balay #undef __FUNCT__
24114a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
24129b94acceSBarry Smith /*@C
24139b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2414044dda88SLois Curfman McInnes    location to store the matrix.
24159b94acceSBarry Smith 
24163f9fe445SBarry Smith    Logically Collective on SNES and Mat
2417c7afd0dbSLois Curfman McInnes 
24189b94acceSBarry Smith    Input Parameters:
2419c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2420e5d3d808SBarry Smith .  Amat - the matrix that defines the (approximate) Jacobian
2421e5d3d808SBarry Smith .  Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat.
2422411c0326SBarry Smith .  J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details
2423c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
24240298fd71SBarry Smith          Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value)
24259b94acceSBarry Smith 
24269b94acceSBarry Smith    Notes:
2427e5d3d808SBarry Smith    If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on
242816913363SBarry Smith    each matrix.
242916913363SBarry Smith 
24308d359177SBarry Smith    If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument
2431a8a26c1eSJed Brown    must be a MatFDColoring.
2432a8a26c1eSJed Brown 
2433c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2434c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2435c3cc8fd1SJed Brown 
243636851e7fSLois Curfman McInnes    Level: beginner
243736851e7fSLois Curfman McInnes 
24389b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
24399b94acceSBarry Smith 
2440411c0326SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESComputeJacobianDefaultColor(), MatStructure, J,
2441411c0326SBarry Smith           SNESSetPicard(), SNESJacobianFunction
24429b94acceSBarry Smith @*/
2443d1e9a80fSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx)
24449b94acceSBarry Smith {
2445dfbe8321SBarry Smith   PetscErrorCode ierr;
24466cab3a1bSJed Brown   DM             dm;
24473a7fca6bSBarry Smith 
24483a40ed3dSBarry Smith   PetscFunctionBegin;
24490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2450e5d3d808SBarry Smith   if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2);
2451e5d3d808SBarry Smith   if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3);
2452e5d3d808SBarry Smith   if (Amat) PetscCheckSameComm(snes,1,Amat,2);
2453e5d3d808SBarry Smith   if (Pmat) PetscCheckSameComm(snes,1,Pmat,3);
24546cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2455f8b49ee9SBarry Smith   ierr = DMSNESSetJacobian(dm,J,ctx);CHKERRQ(ierr);
2456e5d3d808SBarry Smith   if (Amat) {
2457e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Amat);CHKERRQ(ierr);
24586bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
2459f5af7f23SKarl Rupp 
2460e5d3d808SBarry Smith     snes->jacobian = Amat;
24613a7fca6bSBarry Smith   }
2462e5d3d808SBarry Smith   if (Pmat) {
2463e5d3d808SBarry Smith     ierr = PetscObjectReference((PetscObject)Pmat);CHKERRQ(ierr);
24646bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2465f5af7f23SKarl Rupp 
2466e5d3d808SBarry Smith     snes->jacobian_pre = Pmat;
24673a7fca6bSBarry Smith   }
24683a40ed3dSBarry Smith   PetscFunctionReturn(0);
24699b94acceSBarry Smith }
247062fef451SLois Curfman McInnes 
24714a2ae208SSatish Balay #undef __FUNCT__
24724a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2473c2aafc4cSSatish Balay /*@C
2474b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2475b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2476b4fd4287SBarry Smith 
2477c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2478c7afd0dbSLois Curfman McInnes 
2479b4fd4287SBarry Smith    Input Parameter:
2480b4fd4287SBarry Smith .  snes - the nonlinear solver context
2481b4fd4287SBarry Smith 
2482b4fd4287SBarry Smith    Output Parameters:
2483e5d3d808SBarry Smith +  Amat - location to stash (approximate) Jacobian matrix (or NULL)
2484e5d3d808SBarry Smith .  Pmat - location to stash matrix used to compute the preconditioner (or NULL)
2485411c0326SBarry Smith .  J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence
24860298fd71SBarry Smith -  ctx - location to stash Jacobian ctx (or NULL)
2487fee21e36SBarry Smith 
248836851e7fSLois Curfman McInnes    Level: advanced
248936851e7fSLois Curfman McInnes 
2490411c0326SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian(), SNESJacobianFunction, SNESGetFunction()
2491b4fd4287SBarry Smith @*/
2492d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx)
2493b4fd4287SBarry Smith {
24946cab3a1bSJed Brown   PetscErrorCode ierr;
24956cab3a1bSJed Brown   DM             dm;
2496942e3340SBarry Smith   DMSNES         sdm;
24976cab3a1bSJed Brown 
24983a40ed3dSBarry Smith   PetscFunctionBegin;
24990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2500e5d3d808SBarry Smith   if (Amat) *Amat = snes->jacobian;
2501e5d3d808SBarry Smith   if (Pmat) *Pmat = snes->jacobian_pre;
25026cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2503942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2504f8b49ee9SBarry Smith   if (J) *J = sdm->ops->computejacobian;
25056cab3a1bSJed Brown   if (ctx) *ctx = sdm->jacobianctx;
25063a40ed3dSBarry Smith   PetscFunctionReturn(0);
2507b4fd4287SBarry Smith }
2508b4fd4287SBarry Smith 
25094a2ae208SSatish Balay #undef __FUNCT__
25104a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
25119b94acceSBarry Smith /*@
25129b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2513272ac6f2SLois Curfman McInnes    of a nonlinear solver.
25149b94acceSBarry Smith 
2515fee21e36SBarry Smith    Collective on SNES
2516fee21e36SBarry Smith 
2517c7afd0dbSLois Curfman McInnes    Input Parameters:
251870e92668SMatthew Knepley .  snes - the SNES context
2519c7afd0dbSLois Curfman McInnes 
2520272ac6f2SLois Curfman McInnes    Notes:
2521272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2522272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2523272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2524272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2525272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2526272ac6f2SLois Curfman McInnes 
252736851e7fSLois Curfman McInnes    Level: advanced
252836851e7fSLois Curfman McInnes 
25299b94acceSBarry Smith .keywords: SNES, nonlinear, setup
25309b94acceSBarry Smith 
25319b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
25329b94acceSBarry Smith @*/
25337087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
25349b94acceSBarry Smith {
2535dfbe8321SBarry Smith   PetscErrorCode ierr;
25366cab3a1bSJed Brown   DM             dm;
2537942e3340SBarry Smith   DMSNES         sdm;
2538c35f09e5SBarry Smith   SNESLineSearch linesearch, pclinesearch;
25396e2a1849SPeter Brune   void           *lsprectx,*lspostctx;
25406b2b7091SBarry Smith   PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*);
25416b2b7091SBarry Smith   PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*);
25426e2a1849SPeter Brune   PetscErrorCode (*func)(SNES,Vec,Vec,void*);
25436e2a1849SPeter Brune   Vec            f,fpc;
25446e2a1849SPeter Brune   void           *funcctx;
2545d1e9a80fSBarry Smith   PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*);
25461eb13d49SPeter Brune   void           *jacctx,*appctx;
254732b97717SPeter Brune   Mat            j,jpre;
25483a40ed3dSBarry Smith 
25493a40ed3dSBarry Smith   PetscFunctionBegin;
25500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25514dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
25529b94acceSBarry Smith 
25537adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
255404d7464bSBarry Smith     ierr = SNESSetType(snes,SNESNEWTONLS);CHKERRQ(ierr);
255585385478SLisandro Dalcin   }
255685385478SLisandro Dalcin 
25570298fd71SBarry Smith   ierr = SNESGetFunction(snes,&snes->vec_func,NULL,NULL);CHKERRQ(ierr);
255858c9b817SLisandro Dalcin 
25596cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2560942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2561ce94432eSBarry Smith   if (!sdm->ops->computefunction) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
256222c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
25638d359177SBarry Smith     ierr = DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL);CHKERRQ(ierr);
256419f7a02aSBarry Smith   }
25656cab3a1bSJed Brown   if (!snes->vec_func) {
25666cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2567214df951SJed Brown   }
2568efd51863SBarry Smith 
256922d28d08SBarry Smith   if (!snes->ksp) {
257022d28d08SBarry Smith     ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);
257122d28d08SBarry Smith   }
2572b710008aSBarry Smith 
257322d28d08SBarry Smith   if (!snes->linesearch) {
25747601faf0SJed Brown     ierr = SNESGetLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
257522d28d08SBarry Smith   }
2576ed07d7d7SPeter Brune   ierr = SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction);CHKERRQ(ierr);
25779e764e56SPeter Brune 
2578172a4300SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) {
2579172a4300SPeter Brune     snes->mf          = PETSC_TRUE;
2580172a4300SPeter Brune     snes->mf_operator = PETSC_FALSE;
2581172a4300SPeter Brune   }
2582d8f46077SPeter Brune 
25836e2a1849SPeter Brune   if (snes->pc) {
25846e2a1849SPeter Brune     /* copy the DM over */
25856e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
25866e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
25876e2a1849SPeter Brune 
25886e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
25896e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
25906e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
259132b97717SPeter Brune     ierr = SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx);CHKERRQ(ierr);
259232b97717SPeter Brune     ierr = SNESSetJacobian(snes->pc,j,jpre,jac,jacctx);CHKERRQ(ierr);
25931eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
25941eb13d49SPeter Brune     ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr);
25956e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
25966e2a1849SPeter Brune 
25976e2a1849SPeter Brune     /* copy the function pointers over */
25986e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
25996e2a1849SPeter Brune 
26006e2a1849SPeter Brune     /* default to 1 iteration */
2601140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc,0.0,0.0,0.0,1,snes->pc->max_funcs);CHKERRQ(ierr);
2602a9936a0cSPeter Brune     if (snes->pcside==PC_RIGHT) {
2603365a6726SPeter Brune       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
2604a9936a0cSPeter Brune     } else {
2605365a6726SPeter Brune       ierr = SNESSetNormSchedule(snes->pc,SNES_NORM_NONE);CHKERRQ(ierr);
2606a9936a0cSPeter Brune     }
26076e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
26086e2a1849SPeter Brune 
26096e2a1849SPeter Brune     /* copy the line search context over */
26107601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
26117601faf0SJed Brown     ierr = SNESGetLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
26126b2b7091SBarry Smith     ierr = SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx);CHKERRQ(ierr);
26136b2b7091SBarry Smith     ierr = SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx);CHKERRQ(ierr);
26146b2b7091SBarry Smith     ierr = SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx);CHKERRQ(ierr);
26156b2b7091SBarry Smith     ierr = SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx);CHKERRQ(ierr);
26166e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
26176e2a1849SPeter Brune   }
261832b97717SPeter Brune   if (snes->mf) {
261932b97717SPeter Brune     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
262032b97717SPeter Brune   }
262132b97717SPeter Brune   if (snes->ops->usercompute && !snes->user) {
262232b97717SPeter Brune     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
262332b97717SPeter Brune   }
26246e2a1849SPeter Brune 
262537ec4e1aSPeter Brune   snes->jac_iter = 0;
262637ec4e1aSPeter Brune   snes->pre_iter = 0;
262737ec4e1aSPeter Brune 
2628410397dcSLisandro Dalcin   if (snes->ops->setup) {
2629410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2630410397dcSLisandro Dalcin   }
263158c9b817SLisandro Dalcin 
26326c67d002SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) {
26336c67d002SPeter Brune     if (snes->functype == SNES_FUNCTION_PRECONDITIONED) {
263455d4788fSPeter Brune       ierr = SNESGetLineSearch(snes,&linesearch);CHKERRQ(ierr);
2635be95d8f1SBarry Smith       ierr = SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC);CHKERRQ(ierr);
26366c67d002SPeter Brune     }
26376c67d002SPeter Brune   }
26386c67d002SPeter Brune 
26397aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
26403a40ed3dSBarry Smith   PetscFunctionReturn(0);
26419b94acceSBarry Smith }
26429b94acceSBarry Smith 
26434a2ae208SSatish Balay #undef __FUNCT__
264437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
264537596af1SLisandro Dalcin /*@
264637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
264737596af1SLisandro Dalcin 
264837596af1SLisandro Dalcin    Collective on SNES
264937596af1SLisandro Dalcin 
265037596af1SLisandro Dalcin    Input Parameter:
265137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
265237596af1SLisandro Dalcin 
2653d25893d9SBarry Smith    Level: intermediate
2654d25893d9SBarry Smith 
2655d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
265637596af1SLisandro Dalcin 
265737596af1SLisandro Dalcin .keywords: SNES, destroy
265837596af1SLisandro Dalcin 
265937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
266037596af1SLisandro Dalcin @*/
266137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
266237596af1SLisandro Dalcin {
266337596af1SLisandro Dalcin   PetscErrorCode ierr;
266437596af1SLisandro Dalcin 
266537596af1SLisandro Dalcin   PetscFunctionBegin;
266637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2667d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2668d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
26690298fd71SBarry Smith     snes->user = NULL;
2670d25893d9SBarry Smith   }
26718a23116dSBarry Smith   if (snes->pc) {
26728a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
26738a23116dSBarry Smith   }
26748a23116dSBarry Smith 
267537596af1SLisandro Dalcin   if (snes->ops->reset) {
267637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
267737596af1SLisandro Dalcin   }
26789e764e56SPeter Brune   if (snes->ksp) {
26799e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
26809e764e56SPeter Brune   }
26819e764e56SPeter Brune 
26829e764e56SPeter Brune   if (snes->linesearch) {
2683f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
26849e764e56SPeter Brune   }
26859e764e56SPeter Brune 
26866bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
26876bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
26886bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
26896bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
26906bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
26916bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2692c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2693c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
2694f5af7f23SKarl Rupp 
269537596af1SLisandro Dalcin   snes->nwork       = snes->nvwork = 0;
269637596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
269737596af1SLisandro Dalcin   PetscFunctionReturn(0);
269837596af1SLisandro Dalcin }
269937596af1SLisandro Dalcin 
270037596af1SLisandro Dalcin #undef __FUNCT__
27014a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
270252baeb72SSatish Balay /*@
27039b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
27049b94acceSBarry Smith    with SNESCreate().
27059b94acceSBarry Smith 
2706c7afd0dbSLois Curfman McInnes    Collective on SNES
2707c7afd0dbSLois Curfman McInnes 
27089b94acceSBarry Smith    Input Parameter:
27099b94acceSBarry Smith .  snes - the SNES context
27109b94acceSBarry Smith 
271136851e7fSLois Curfman McInnes    Level: beginner
271236851e7fSLois Curfman McInnes 
27139b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
27149b94acceSBarry Smith 
271563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
27169b94acceSBarry Smith @*/
27176bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
27189b94acceSBarry Smith {
27196849ba73SBarry Smith   PetscErrorCode ierr;
27203a40ed3dSBarry Smith 
27213a40ed3dSBarry Smith   PetscFunctionBegin;
27226bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
27236bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
27246bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2725d4bb536fSBarry Smith 
27266bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
27278a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
27286b8b9a38SLisandro Dalcin 
2729e04113cfSBarry Smith   /* if memory was published with SAWs then destroy it */
2730e04113cfSBarry Smith   ierr = PetscObjectSAWsViewOff((PetscObject)*snes);CHKERRQ(ierr);
27316bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
27326d4c513bSLisandro Dalcin 
27336bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
27346bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2735f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
27366b8b9a38SLisandro Dalcin 
27376bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
27386bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
27396bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
27406b8b9a38SLisandro Dalcin   }
27416bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
27426bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
27436bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
274458c9b817SLisandro Dalcin   }
27456bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2746a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
27473a40ed3dSBarry Smith   PetscFunctionReturn(0);
27489b94acceSBarry Smith }
27499b94acceSBarry Smith 
27509b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
27519b94acceSBarry Smith 
27524a2ae208SSatish Balay #undef __FUNCT__
2753a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2754a8054027SBarry Smith /*@
2755a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2756a8054027SBarry Smith 
27573f9fe445SBarry Smith    Logically Collective on SNES
2758a8054027SBarry Smith 
2759a8054027SBarry Smith    Input Parameters:
2760a8054027SBarry Smith +  snes - the SNES context
2761a8054027SBarry 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
27623b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2763a8054027SBarry Smith 
2764a8054027SBarry Smith    Options Database Keys:
2765a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2766a8054027SBarry Smith 
2767a8054027SBarry Smith    Notes:
2768a8054027SBarry Smith    The default is 1
2769a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2770a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2771a8054027SBarry Smith 
2772a8054027SBarry Smith    Level: intermediate
2773a8054027SBarry Smith 
2774a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2775a8054027SBarry Smith 
2776e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2777a8054027SBarry Smith 
2778a8054027SBarry Smith @*/
27797087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2780a8054027SBarry Smith {
2781a8054027SBarry Smith   PetscFunctionBegin;
27820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2783e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2784e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2785c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2786a8054027SBarry Smith   snes->lagpreconditioner = lag;
2787a8054027SBarry Smith   PetscFunctionReturn(0);
2788a8054027SBarry Smith }
2789a8054027SBarry Smith 
2790a8054027SBarry Smith #undef __FUNCT__
2791efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2792efd51863SBarry Smith /*@
2793efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2794efd51863SBarry Smith 
2795efd51863SBarry Smith    Logically Collective on SNES
2796efd51863SBarry Smith 
2797efd51863SBarry Smith    Input Parameters:
2798efd51863SBarry Smith +  snes - the SNES context
2799efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2800efd51863SBarry Smith 
2801efd51863SBarry Smith    Options Database Keys:
2802efd51863SBarry Smith .    -snes_grid_sequence <steps>
2803efd51863SBarry Smith 
2804efd51863SBarry Smith    Level: intermediate
2805efd51863SBarry Smith 
2806c0df2a02SJed Brown    Notes:
2807c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2808c0df2a02SJed Brown 
2809efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2810efd51863SBarry Smith 
2811efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2812efd51863SBarry Smith 
2813efd51863SBarry Smith @*/
2814efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2815efd51863SBarry Smith {
2816efd51863SBarry Smith   PetscFunctionBegin;
2817efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2818efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2819efd51863SBarry Smith   snes->gridsequence = steps;
2820efd51863SBarry Smith   PetscFunctionReturn(0);
2821efd51863SBarry Smith }
2822efd51863SBarry Smith 
2823efd51863SBarry Smith #undef __FUNCT__
2824a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2825a8054027SBarry Smith /*@
2826a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2827a8054027SBarry Smith 
28283f9fe445SBarry Smith    Not Collective
2829a8054027SBarry Smith 
2830a8054027SBarry Smith    Input Parameter:
2831a8054027SBarry Smith .  snes - the SNES context
2832a8054027SBarry Smith 
2833a8054027SBarry Smith    Output Parameter:
2834a8054027SBarry 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
28353b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2836a8054027SBarry Smith 
2837a8054027SBarry Smith    Options Database Keys:
2838a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2839a8054027SBarry Smith 
2840a8054027SBarry Smith    Notes:
2841a8054027SBarry Smith    The default is 1
2842a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2843a8054027SBarry Smith 
2844a8054027SBarry Smith    Level: intermediate
2845a8054027SBarry Smith 
2846a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2847a8054027SBarry Smith 
2848a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2849a8054027SBarry Smith 
2850a8054027SBarry Smith @*/
28517087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2852a8054027SBarry Smith {
2853a8054027SBarry Smith   PetscFunctionBegin;
28540700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2855a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2856a8054027SBarry Smith   PetscFunctionReturn(0);
2857a8054027SBarry Smith }
2858a8054027SBarry Smith 
2859a8054027SBarry Smith #undef __FUNCT__
2860e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2861e35cf81dSBarry Smith /*@
2862e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2863e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2864e35cf81dSBarry Smith 
28653f9fe445SBarry Smith    Logically Collective on SNES
2866e35cf81dSBarry Smith 
2867e35cf81dSBarry Smith    Input Parameters:
2868e35cf81dSBarry Smith +  snes - the SNES context
2869e35cf81dSBarry 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
2870fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2871e35cf81dSBarry Smith 
2872e35cf81dSBarry Smith    Options Database Keys:
2873e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2874e35cf81dSBarry Smith 
2875e35cf81dSBarry Smith    Notes:
2876e35cf81dSBarry Smith    The default is 1
2877e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2878fe3ffe1eSBarry 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
2879fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2880e35cf81dSBarry Smith 
2881e35cf81dSBarry Smith    Level: intermediate
2882e35cf81dSBarry Smith 
2883e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2884e35cf81dSBarry Smith 
2885e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2886e35cf81dSBarry Smith 
2887e35cf81dSBarry Smith @*/
28887087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2889e35cf81dSBarry Smith {
2890e35cf81dSBarry Smith   PetscFunctionBegin;
28910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2892e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2893e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2894c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2895e35cf81dSBarry Smith   snes->lagjacobian = lag;
2896e35cf81dSBarry Smith   PetscFunctionReturn(0);
2897e35cf81dSBarry Smith }
2898e35cf81dSBarry Smith 
2899e35cf81dSBarry Smith #undef __FUNCT__
2900e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2901e35cf81dSBarry Smith /*@
2902e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2903e35cf81dSBarry Smith 
29043f9fe445SBarry Smith    Not Collective
2905e35cf81dSBarry Smith 
2906e35cf81dSBarry Smith    Input Parameter:
2907e35cf81dSBarry Smith .  snes - the SNES context
2908e35cf81dSBarry Smith 
2909e35cf81dSBarry Smith    Output Parameter:
2910e35cf81dSBarry 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
2911e35cf81dSBarry Smith          the Jacobian is built etc.
2912e35cf81dSBarry Smith 
2913e35cf81dSBarry Smith    Options Database Keys:
2914e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2915e35cf81dSBarry Smith 
2916e35cf81dSBarry Smith    Notes:
2917e35cf81dSBarry Smith    The default is 1
2918e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2919e35cf81dSBarry Smith 
2920e35cf81dSBarry Smith    Level: intermediate
2921e35cf81dSBarry Smith 
2922e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2923e35cf81dSBarry Smith 
2924e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2925e35cf81dSBarry Smith 
2926e35cf81dSBarry Smith @*/
29277087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2928e35cf81dSBarry Smith {
2929e35cf81dSBarry Smith   PetscFunctionBegin;
29300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2931e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2932e35cf81dSBarry Smith   PetscFunctionReturn(0);
2933e35cf81dSBarry Smith }
2934e35cf81dSBarry Smith 
2935e35cf81dSBarry Smith #undef __FUNCT__
293637ec4e1aSPeter Brune #define __FUNCT__ "SNESSetLagJacobianPersists"
293737ec4e1aSPeter Brune /*@
293837ec4e1aSPeter Brune    SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves
293937ec4e1aSPeter Brune 
294037ec4e1aSPeter Brune    Logically collective on SNES
294137ec4e1aSPeter Brune 
294237ec4e1aSPeter Brune    Input Parameter:
294337ec4e1aSPeter Brune +  snes - the SNES context
29449d7e2deaSPeter Brune -   flg - jacobian lagging persists if true
294537ec4e1aSPeter Brune 
294637ec4e1aSPeter Brune    Options Database Keys:
294737ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
294837ec4e1aSPeter Brune 
294937ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by
295037ec4e1aSPeter Brune    several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several
295137ec4e1aSPeter Brune    timesteps may present huge efficiency gains.
295237ec4e1aSPeter Brune 
295337ec4e1aSPeter Brune    Level: developer
295437ec4e1aSPeter Brune 
2955be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
295637ec4e1aSPeter Brune 
2957be95d8f1SBarry Smith .seealso: SNESSetLagPreconditionerPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
295837ec4e1aSPeter Brune 
295937ec4e1aSPeter Brune @*/
296037ec4e1aSPeter Brune PetscErrorCode  SNESSetLagJacobianPersists(SNES snes,PetscBool flg)
296137ec4e1aSPeter Brune {
296237ec4e1aSPeter Brune   PetscFunctionBegin;
296337ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
296437ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
296537ec4e1aSPeter Brune   snes->lagjac_persist = flg;
296637ec4e1aSPeter Brune   PetscFunctionReturn(0);
296737ec4e1aSPeter Brune }
296837ec4e1aSPeter Brune 
296937ec4e1aSPeter Brune #undef __FUNCT__
297037ec4e1aSPeter Brune #define __FUNCT__ "SNESSetLagPreconditionerPersists"
297137ec4e1aSPeter Brune /*@
297237ec4e1aSPeter Brune    SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple solves
297337ec4e1aSPeter Brune 
297437ec4e1aSPeter Brune    Logically Collective on SNES
297537ec4e1aSPeter Brune 
297637ec4e1aSPeter Brune    Input Parameter:
297737ec4e1aSPeter Brune +  snes - the SNES context
29789d7e2deaSPeter Brune -   flg - preconditioner lagging persists if true
297937ec4e1aSPeter Brune 
298037ec4e1aSPeter Brune    Options Database Keys:
298137ec4e1aSPeter Brune .    -snes_lag_jacobian_persists <flg>
298237ec4e1aSPeter Brune 
298337ec4e1aSPeter Brune    Notes: This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale
298437ec4e1aSPeter Brune    by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over
298537ec4e1aSPeter Brune    several timesteps may present huge efficiency gains.
298637ec4e1aSPeter Brune 
298737ec4e1aSPeter Brune    Level: developer
298837ec4e1aSPeter Brune 
2989be95d8f1SBarry Smith .keywords: SNES, nonlinear, lag
299037ec4e1aSPeter Brune 
2991be95d8f1SBarry Smith .seealso: SNESSetLagJacobianPersists(), SNESSetLagJacobian(), SNESGetLagJacobian(), SNESGetNPC()
299237ec4e1aSPeter Brune 
299337ec4e1aSPeter Brune @*/
299437ec4e1aSPeter Brune PetscErrorCode  SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg)
299537ec4e1aSPeter Brune {
299637ec4e1aSPeter Brune   PetscFunctionBegin;
299737ec4e1aSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
299837ec4e1aSPeter Brune   PetscValidLogicalCollectiveBool(snes,flg,2);
299937ec4e1aSPeter Brune   snes->lagpre_persist = flg;
300037ec4e1aSPeter Brune   PetscFunctionReturn(0);
300137ec4e1aSPeter Brune }
300237ec4e1aSPeter Brune 
300337ec4e1aSPeter Brune #undef __FUNCT__
30044a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
30059b94acceSBarry Smith /*@
3006d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
30079b94acceSBarry Smith 
30083f9fe445SBarry Smith    Logically Collective on SNES
3009c7afd0dbSLois Curfman McInnes 
30109b94acceSBarry Smith    Input Parameters:
3011c7afd0dbSLois Curfman McInnes +  snes - the SNES context
301270441072SBarry Smith .  abstol - absolute convergence tolerance
301333174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
30145358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
301533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3016c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3017fee21e36SBarry Smith 
301833174efeSLois Curfman McInnes    Options Database Keys:
301970441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
3020c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
3021c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
3022c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
3023c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
30249b94acceSBarry Smith 
3025d7a720efSLois Curfman McInnes    Notes:
30269b94acceSBarry Smith    The default maximum number of iterations is 50.
30279b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
30289b94acceSBarry Smith 
302936851e7fSLois Curfman McInnes    Level: intermediate
303036851e7fSLois Curfman McInnes 
303133174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
30329b94acceSBarry Smith 
30332492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
30349b94acceSBarry Smith @*/
30357087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
30369b94acceSBarry Smith {
30373a40ed3dSBarry Smith   PetscFunctionBegin;
30380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3039c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
3040c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
3041c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
3042c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
3043c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
3044c5eb9154SBarry Smith 
3045ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
304657622a8eSBarry Smith     if (abstol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol);
3047ab54825eSJed Brown     snes->abstol = abstol;
3048ab54825eSJed Brown   }
3049ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
305057622a8eSBarry 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);
3051ab54825eSJed Brown     snes->rtol = rtol;
3052ab54825eSJed Brown   }
3053ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
305457622a8eSBarry Smith     if (stol < 0.0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol);
3055c60f73f4SPeter Brune     snes->stol = stol;
3056ab54825eSJed Brown   }
3057ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
3058ce94432eSBarry Smith     if (maxit < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
3059ab54825eSJed Brown     snes->max_its = maxit;
3060ab54825eSJed Brown   }
3061ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
3062ce94432eSBarry Smith     if (maxf < 0) SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
3063ab54825eSJed Brown     snes->max_funcs = maxf;
3064ab54825eSJed Brown   }
306588976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
30663a40ed3dSBarry Smith   PetscFunctionReturn(0);
30679b94acceSBarry Smith }
30689b94acceSBarry Smith 
30694a2ae208SSatish Balay #undef __FUNCT__
30704a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
30719b94acceSBarry Smith /*@
307233174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
307333174efeSLois Curfman McInnes 
3074c7afd0dbSLois Curfman McInnes    Not Collective
3075c7afd0dbSLois Curfman McInnes 
307633174efeSLois Curfman McInnes    Input Parameters:
3077c7afd0dbSLois Curfman McInnes +  snes - the SNES context
307885385478SLisandro Dalcin .  atol - absolute convergence tolerance
307933174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
308033174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
308133174efeSLois Curfman McInnes            of the change in the solution between steps
308233174efeSLois Curfman McInnes .  maxit - maximum number of iterations
3083c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
3084fee21e36SBarry Smith 
308533174efeSLois Curfman McInnes    Notes:
30860298fd71SBarry Smith    The user can specify NULL for any parameter that is not needed.
308733174efeSLois Curfman McInnes 
308836851e7fSLois Curfman McInnes    Level: intermediate
308936851e7fSLois Curfman McInnes 
309033174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
309133174efeSLois Curfman McInnes 
309233174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
309333174efeSLois Curfman McInnes @*/
30947087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
309533174efeSLois Curfman McInnes {
30963a40ed3dSBarry Smith   PetscFunctionBegin;
30970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
309885385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
309933174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
3100c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
310133174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
310233174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
31033a40ed3dSBarry Smith   PetscFunctionReturn(0);
310433174efeSLois Curfman McInnes }
310533174efeSLois Curfman McInnes 
31064a2ae208SSatish Balay #undef __FUNCT__
31074a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
310833174efeSLois Curfman McInnes /*@
31099b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
31109b94acceSBarry Smith 
31113f9fe445SBarry Smith    Logically Collective on SNES
3112fee21e36SBarry Smith 
3113c7afd0dbSLois Curfman McInnes    Input Parameters:
3114c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3115c7afd0dbSLois Curfman McInnes -  tol - tolerance
3116c7afd0dbSLois Curfman McInnes 
31179b94acceSBarry Smith    Options Database Key:
3118c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
31199b94acceSBarry Smith 
312036851e7fSLois Curfman McInnes    Level: intermediate
312136851e7fSLois Curfman McInnes 
31229b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
31239b94acceSBarry Smith 
31242492ecdbSBarry Smith .seealso: SNESSetTolerances()
31259b94acceSBarry Smith @*/
31267087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
31279b94acceSBarry Smith {
31283a40ed3dSBarry Smith   PetscFunctionBegin;
31290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3130c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
31319b94acceSBarry Smith   snes->deltatol = tol;
31323a40ed3dSBarry Smith   PetscFunctionReturn(0);
31339b94acceSBarry Smith }
31349b94acceSBarry Smith 
3135df9fa365SBarry Smith /*
3136df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3137df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3138df9fa365SBarry Smith    macros instead of functions
3139df9fa365SBarry Smith */
31404a2ae208SSatish Balay #undef __FUNCT__
31414619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm"
31423e7ff0edSBarry Smith PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,PetscObject *objs)
3143ce1608b8SBarry Smith {
3144dfbe8321SBarry Smith   PetscErrorCode ierr;
3145ce1608b8SBarry Smith 
3146ce1608b8SBarry Smith   PetscFunctionBegin;
31470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31483e7ff0edSBarry Smith   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,objs);CHKERRQ(ierr);
3149ce1608b8SBarry Smith   PetscFunctionReturn(0);
3150ce1608b8SBarry Smith }
3151ce1608b8SBarry Smith 
31524a2ae208SSatish Balay #undef __FUNCT__
3153a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
3154435c5a64SBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscObject **draw)
3155df9fa365SBarry Smith {
3156dfbe8321SBarry Smith   PetscErrorCode ierr;
3157df9fa365SBarry Smith 
3158df9fa365SBarry Smith   PetscFunctionBegin;
31591d1e9da1SBarry Smith   ierr = KSPMonitorLGResidualNormCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
3160df9fa365SBarry Smith   PetscFunctionReturn(0);
3161df9fa365SBarry Smith }
3162df9fa365SBarry Smith 
31634a2ae208SSatish Balay #undef __FUNCT__
3164a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
31653e7ff0edSBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscObject **objs)
3166df9fa365SBarry Smith {
3167dfbe8321SBarry Smith   PetscErrorCode ierr;
3168df9fa365SBarry Smith 
3169df9fa365SBarry Smith   PetscFunctionBegin;
31703e7ff0edSBarry Smith   ierr = KSPMonitorLGResidualNormDestroy(objs);CHKERRQ(ierr);
3171df9fa365SBarry Smith   PetscFunctionReturn(0);
3172df9fa365SBarry Smith }
3173df9fa365SBarry Smith 
31747087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3175b271bb04SBarry Smith #undef __FUNCT__
3176b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
31777087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3178b271bb04SBarry Smith {
3179b271bb04SBarry Smith   PetscDrawLG      lg;
3180b271bb04SBarry Smith   PetscErrorCode   ierr;
3181b271bb04SBarry Smith   PetscReal        x,y,per;
3182b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3183b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3184b271bb04SBarry Smith   PetscDraw        draw;
3185b271bb04SBarry Smith 
3186459f5d12SBarry Smith   PetscFunctionBegin;
3187b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3188b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3189b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3190b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3191b271bb04SBarry Smith   x    = (PetscReal)n;
319277b4d14cSPeter Brune   if (rnorm > 0.0) y = PetscLog10Real(rnorm);
319394c9c6d3SKarl Rupp   else y = -15.0;
3194b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3195b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3196b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3197b271bb04SBarry Smith   }
3198b271bb04SBarry Smith 
3199b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3200b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3201b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3202b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3203b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3204b271bb04SBarry Smith   x    = (PetscReal)n;
3205b271bb04SBarry Smith   y    = 100.0*per;
3206b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3207b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3208b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3209b271bb04SBarry Smith   }
3210b271bb04SBarry Smith 
3211b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3212b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3213b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3214b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3215b271bb04SBarry Smith   x    = (PetscReal)n;
3216b271bb04SBarry Smith   y    = (prev - rnorm)/prev;
3217b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3218b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3219b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3220b271bb04SBarry Smith   }
3221b271bb04SBarry Smith 
3222b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3223b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3224b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3225b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3226b271bb04SBarry Smith   x    = (PetscReal)n;
3227b271bb04SBarry Smith   y    = (prev - rnorm)/(prev*per);
3228b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3229b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3230b271bb04SBarry Smith   }
3231b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3232b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3233b271bb04SBarry Smith   }
3234b271bb04SBarry Smith   prev = rnorm;
3235b271bb04SBarry Smith   PetscFunctionReturn(0);
3236b271bb04SBarry Smith }
3237b271bb04SBarry Smith 
3238b271bb04SBarry Smith #undef __FUNCT__
32397a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
3240228d79bcSJed Brown /*@
3241228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3242228d79bcSJed Brown 
3243228d79bcSJed Brown    Collective on SNES
3244228d79bcSJed Brown 
3245228d79bcSJed Brown    Input Parameters:
3246228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3247228d79bcSJed Brown .  iter - iteration number
3248228d79bcSJed Brown -  rnorm - relative norm of the residual
3249228d79bcSJed Brown 
3250228d79bcSJed Brown    Notes:
3251228d79bcSJed Brown    This routine is called by the SNES implementations.
3252228d79bcSJed Brown    It does not typically need to be called by the user.
3253228d79bcSJed Brown 
3254228d79bcSJed Brown    Level: developer
3255228d79bcSJed Brown 
3256228d79bcSJed Brown .seealso: SNESMonitorSet()
3257228d79bcSJed Brown @*/
32587a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
32597a03ce2fSLisandro Dalcin {
32607a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
32617a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
32627a03ce2fSLisandro Dalcin 
32637a03ce2fSLisandro Dalcin   PetscFunctionBegin;
32645edff71fSBarry Smith   ierr = VecLockPush(snes->vec_sol);CHKERRQ(ierr);
32657a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
32667a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
32677a03ce2fSLisandro Dalcin   }
32685edff71fSBarry Smith   ierr = VecLockPop(snes->vec_sol);CHKERRQ(ierr);
32697a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
32707a03ce2fSLisandro Dalcin }
32717a03ce2fSLisandro Dalcin 
32729b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
32739b94acceSBarry Smith 
3274bf388a1fSBarry Smith /*MC
3275bf388a1fSBarry Smith     SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver
3276bf388a1fSBarry Smith 
3277bf388a1fSBarry Smith      Synopsis:
3278aaa7dc30SBarry Smith      #include <petscsnes.h>
3279bf388a1fSBarry Smith $    PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3280bf388a1fSBarry Smith 
3281bf388a1fSBarry Smith +    snes - the SNES context
3282bf388a1fSBarry Smith .    its - iteration number
3283bf388a1fSBarry Smith .    norm - 2-norm function value (may be estimated)
3284bf388a1fSBarry Smith -    mctx - [optional] monitoring context
3285bf388a1fSBarry Smith 
3286878cb397SSatish Balay    Level: advanced
3287878cb397SSatish Balay 
3288bf388a1fSBarry Smith .seealso:   SNESMonitorSet(), SNESMonitorGet()
3289bf388a1fSBarry Smith M*/
3290bf388a1fSBarry Smith 
32914a2ae208SSatish Balay #undef __FUNCT__
3292a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
32939b94acceSBarry Smith /*@C
3294a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
32959b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
32969b94acceSBarry Smith    progress.
32979b94acceSBarry Smith 
32983f9fe445SBarry Smith    Logically Collective on SNES
3299fee21e36SBarry Smith 
3300c7afd0dbSLois Curfman McInnes    Input Parameters:
3301c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33026e4dcb14SBarry Smith .  f - the monitor function, see SNESMonitorFunction for the calling sequence
3303b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
33040298fd71SBarry Smith           monitor routine (use NULL if no context is desired)
3305b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
33060298fd71SBarry Smith           (may be NULL)
33079b94acceSBarry Smith 
33089665c990SLois Curfman McInnes    Options Database Keys:
3309a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
33104619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3311a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3312cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3313c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3314a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3315c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3316c7afd0dbSLois Curfman McInnes                             the options database.
33179665c990SLois Curfman McInnes 
3318639f9d9dSBarry Smith    Notes:
33196bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3320a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
33216bc08f3fSLois Curfman McInnes    order in which they were set.
3322639f9d9dSBarry Smith 
3323025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3324025f1a04SBarry Smith 
332536851e7fSLois Curfman McInnes    Level: intermediate
332636851e7fSLois Curfman McInnes 
33279b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
33289b94acceSBarry Smith 
3329bf388a1fSBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel(), SNESMonitorFunction
33309b94acceSBarry Smith @*/
33316e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
33329b94acceSBarry Smith {
3333b90d0a6eSBarry Smith   PetscInt       i;
3334649052a6SBarry Smith   PetscErrorCode ierr;
3335b90d0a6eSBarry Smith 
33363a40ed3dSBarry Smith   PetscFunctionBegin;
33370700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
333817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3339b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
33406e4dcb14SBarry Smith     if (f == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3341649052a6SBarry Smith       if (monitordestroy) {
3342c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3343649052a6SBarry Smith       }
3344b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3345b90d0a6eSBarry Smith     }
3346b90d0a6eSBarry Smith   }
33476e4dcb14SBarry Smith   snes->monitor[snes->numbermonitors]          = f;
3348b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]   = monitordestroy;
3349639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
33503a40ed3dSBarry Smith   PetscFunctionReturn(0);
33519b94acceSBarry Smith }
33529b94acceSBarry Smith 
33534a2ae208SSatish Balay #undef __FUNCT__
3354a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
3355a278d85bSSatish Balay /*@
3356a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
33575cd90555SBarry Smith 
33583f9fe445SBarry Smith    Logically Collective on SNES
3359c7afd0dbSLois Curfman McInnes 
33605cd90555SBarry Smith    Input Parameters:
33615cd90555SBarry Smith .  snes - the SNES context
33625cd90555SBarry Smith 
33631a480d89SAdministrator    Options Database Key:
3364a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3365a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3366c7afd0dbSLois Curfman McInnes     set via the options database
33675cd90555SBarry Smith 
33685cd90555SBarry Smith    Notes:
33695cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
33705cd90555SBarry Smith 
337136851e7fSLois Curfman McInnes    Level: intermediate
337236851e7fSLois Curfman McInnes 
33735cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
33745cd90555SBarry Smith 
3375a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
33765cd90555SBarry Smith @*/
33777087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
33785cd90555SBarry Smith {
3379d952e501SBarry Smith   PetscErrorCode ierr;
3380d952e501SBarry Smith   PetscInt       i;
3381d952e501SBarry Smith 
33825cd90555SBarry Smith   PetscFunctionBegin;
33830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3384d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3385d952e501SBarry Smith     if (snes->monitordestroy[i]) {
33863c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3387d952e501SBarry Smith     }
3388d952e501SBarry Smith   }
33895cd90555SBarry Smith   snes->numbermonitors = 0;
33905cd90555SBarry Smith   PetscFunctionReturn(0);
33915cd90555SBarry Smith }
33925cd90555SBarry Smith 
3393bf388a1fSBarry Smith /*MC
3394bf388a1fSBarry Smith     SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver
3395bf388a1fSBarry Smith 
3396bf388a1fSBarry Smith      Synopsis:
3397aaa7dc30SBarry Smith      #include <petscsnes.h>
3398bf388a1fSBarry Smith $     PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3399bf388a1fSBarry Smith 
3400bf388a1fSBarry Smith +    snes - the SNES context
3401bf388a1fSBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3402bf388a1fSBarry Smith .    cctx - [optional] convergence context
3403bf388a1fSBarry Smith .    reason - reason for convergence/divergence
3404bf388a1fSBarry Smith .    xnorm - 2-norm of current iterate
3405bf388a1fSBarry Smith .    gnorm - 2-norm of current step
3406bf388a1fSBarry Smith -    f - 2-norm of function
3407bf388a1fSBarry Smith 
3408878cb397SSatish Balay    Level: intermediate
3409bf388a1fSBarry Smith 
3410bf388a1fSBarry Smith .seealso:   SNESSetConvergenceTest(), SNESGetConvergenceTest()
3411bf388a1fSBarry Smith M*/
3412bf388a1fSBarry Smith 
34134a2ae208SSatish Balay #undef __FUNCT__
34144a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
34159b94acceSBarry Smith /*@C
34169b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
34179b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
34189b94acceSBarry Smith 
34193f9fe445SBarry Smith    Logically Collective on SNES
3420fee21e36SBarry Smith 
3421c7afd0dbSLois Curfman McInnes    Input Parameters:
3422c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3423bf388a1fSBarry Smith .  SNESConvergenceTestFunction - routine to test for convergence
34240298fd71SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be NULL)
34250298fd71SBarry Smith -  destroy - [optional] destructor for the context (may be NULL; NULL_FUNCTION in Fortran)
34269b94acceSBarry Smith 
342736851e7fSLois Curfman McInnes    Level: advanced
342836851e7fSLois Curfman McInnes 
34299b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
34309b94acceSBarry Smith 
3431e2a6519dSDmitry Karpeev .seealso: SNESConvergedDefault(), SNESConvergedSkip(), SNESConvergenceTestFunction
34329b94acceSBarry Smith @*/
3433bf388a1fSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
34349b94acceSBarry Smith {
34357f7931b9SBarry Smith   PetscErrorCode ierr;
34367f7931b9SBarry Smith 
34373a40ed3dSBarry Smith   PetscFunctionBegin;
34380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3439e2a6519dSDmitry Karpeev   if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip;
34407f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
34417f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
34427f7931b9SBarry Smith   }
3443bf388a1fSBarry Smith   snes->ops->converged        = SNESConvergenceTestFunction;
34447f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
344585385478SLisandro Dalcin   snes->cnvP                  = cctx;
34463a40ed3dSBarry Smith   PetscFunctionReturn(0);
34479b94acceSBarry Smith }
34489b94acceSBarry Smith 
34494a2ae208SSatish Balay #undef __FUNCT__
34504a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
345152baeb72SSatish Balay /*@
3452184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3453184914b5SBarry Smith 
3454184914b5SBarry Smith    Not Collective
3455184914b5SBarry Smith 
3456184914b5SBarry Smith    Input Parameter:
3457184914b5SBarry Smith .  snes - the SNES context
3458184914b5SBarry Smith 
3459184914b5SBarry Smith    Output Parameter:
34604d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3461184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3462184914b5SBarry Smith 
3463184914b5SBarry Smith    Level: intermediate
3464184914b5SBarry Smith 
3465184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3466184914b5SBarry Smith 
3467184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3468184914b5SBarry Smith 
346985385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3470184914b5SBarry Smith @*/
34717087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3472184914b5SBarry Smith {
3473184914b5SBarry Smith   PetscFunctionBegin;
34740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34754482741eSBarry Smith   PetscValidPointer(reason,2);
3476184914b5SBarry Smith   *reason = snes->reason;
3477184914b5SBarry Smith   PetscFunctionReturn(0);
3478184914b5SBarry Smith }
3479184914b5SBarry Smith 
34804a2ae208SSatish Balay #undef __FUNCT__
34814a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3482c9005455SLois Curfman McInnes /*@
3483c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3484c9005455SLois Curfman McInnes 
34853f9fe445SBarry Smith    Logically Collective on SNES
3486fee21e36SBarry Smith 
3487c7afd0dbSLois Curfman McInnes    Input Parameters:
3488c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
34898c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3490cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3491758f92a0SBarry Smith .  na  - size of a and its
349264731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3493758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3494c7afd0dbSLois Curfman McInnes 
3495308dcc3eSBarry Smith    Notes:
34960298fd71SBarry Smith    If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3497308dcc3eSBarry Smith    default array of length 10000 is allocated.
3498308dcc3eSBarry Smith 
3499c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3500c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3501c9005455SLois Curfman McInnes    during the section of code that is being timed.
3502c9005455SLois Curfman McInnes 
350336851e7fSLois Curfman McInnes    Level: intermediate
350436851e7fSLois Curfman McInnes 
3505c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3506758f92a0SBarry Smith 
350708405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3508758f92a0SBarry Smith 
3509c9005455SLois Curfman McInnes @*/
35107087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
3511c9005455SLois Curfman McInnes {
3512308dcc3eSBarry Smith   PetscErrorCode ierr;
3513308dcc3eSBarry Smith 
35143a40ed3dSBarry Smith   PetscFunctionBegin;
35150700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35167a1ec6d4SBarry Smith   if (a) PetscValidScalarPointer(a,2);
3517a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
35187a1ec6d4SBarry Smith   if (!a) {
3519308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
35207fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&a);CHKERRQ(ierr);
35217fdeb8b9SBarry Smith     ierr = PetscCalloc1(na,&its);CHKERRQ(ierr);
3522f5af7f23SKarl Rupp 
3523308dcc3eSBarry Smith     snes->conv_malloc = PETSC_TRUE;
3524308dcc3eSBarry Smith   }
3525c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3526758f92a0SBarry Smith   snes->conv_hist_its   = its;
3527758f92a0SBarry Smith   snes->conv_hist_max   = na;
3528a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3529758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3530758f92a0SBarry Smith   PetscFunctionReturn(0);
3531758f92a0SBarry Smith }
3532758f92a0SBarry Smith 
3533308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3534c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3535c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
353699e0435eSBarry Smith 
3537308dcc3eSBarry Smith #undef __FUNCT__
3538308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
35398cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3540308dcc3eSBarry Smith {
3541308dcc3eSBarry Smith   mxArray   *mat;
3542308dcc3eSBarry Smith   PetscInt  i;
3543308dcc3eSBarry Smith   PetscReal *ar;
3544308dcc3eSBarry Smith 
3545308dcc3eSBarry Smith   PetscFunctionBegin;
3546308dcc3eSBarry Smith   mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3547308dcc3eSBarry Smith   ar  = (PetscReal*) mxGetData(mat);
3548f5af7f23SKarl Rupp   for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i];
3549308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3550308dcc3eSBarry Smith }
3551308dcc3eSBarry Smith #endif
3552308dcc3eSBarry Smith 
35534a2ae208SSatish Balay #undef __FUNCT__
35544a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
35550c4c9dddSBarry Smith /*@C
3556758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3557758f92a0SBarry Smith 
35583f9fe445SBarry Smith    Not Collective
3559758f92a0SBarry Smith 
3560758f92a0SBarry Smith    Input Parameter:
3561758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3562758f92a0SBarry Smith 
3563758f92a0SBarry Smith    Output Parameters:
3564758f92a0SBarry Smith .  a   - array to hold history
3565758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3566758f92a0SBarry Smith          negative if not converged) for each solve.
3567758f92a0SBarry Smith -  na  - size of a and its
3568758f92a0SBarry Smith 
3569758f92a0SBarry Smith    Notes:
3570758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3571758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3572758f92a0SBarry Smith 
3573758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3574758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3575758f92a0SBarry Smith    during the section of code that is being timed.
3576758f92a0SBarry Smith 
3577758f92a0SBarry Smith    Level: intermediate
3578758f92a0SBarry Smith 
3579758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3580758f92a0SBarry Smith 
3581758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3582758f92a0SBarry Smith 
3583758f92a0SBarry Smith @*/
35847087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3585758f92a0SBarry Smith {
3586758f92a0SBarry Smith   PetscFunctionBegin;
35870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3588758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3589758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3590758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
35913a40ed3dSBarry Smith   PetscFunctionReturn(0);
3592c9005455SLois Curfman McInnes }
3593c9005455SLois Curfman McInnes 
3594e74ef692SMatthew Knepley #undef __FUNCT__
3595e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3596ac226902SBarry Smith /*@C
359776b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3598eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
35997e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
360076b2cf59SMatthew Knepley 
36013f9fe445SBarry Smith   Logically Collective on SNES
360276b2cf59SMatthew Knepley 
360376b2cf59SMatthew Knepley   Input Parameters:
360476b2cf59SMatthew Knepley . snes - The nonlinear solver context
360576b2cf59SMatthew Knepley . func - The function
360676b2cf59SMatthew Knepley 
360776b2cf59SMatthew Knepley   Calling sequence of func:
3608b5d30489SBarry Smith . func (SNES snes, PetscInt step);
360976b2cf59SMatthew Knepley 
361076b2cf59SMatthew Knepley . step - The current step of the iteration
361176b2cf59SMatthew Knepley 
3612fe97e370SBarry Smith   Level: advanced
3613fe97e370SBarry Smith 
3614fe97e370SBarry 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()
3615fe97e370SBarry Smith         This is not used by most users.
361676b2cf59SMatthew Knepley 
361776b2cf59SMatthew Knepley .keywords: SNES, update
3618b5d30489SBarry Smith 
36198d359177SBarry Smith .seealso SNESSetJacobian(), SNESSolve()
362076b2cf59SMatthew Knepley @*/
36217087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
362276b2cf59SMatthew Knepley {
362376b2cf59SMatthew Knepley   PetscFunctionBegin;
36240700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3625e7788613SBarry Smith   snes->ops->update = func;
362676b2cf59SMatthew Knepley   PetscFunctionReturn(0);
362776b2cf59SMatthew Knepley }
362876b2cf59SMatthew Knepley 
3629e74ef692SMatthew Knepley #undef __FUNCT__
36304a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
36319b94acceSBarry Smith /*
36329b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
36339b94acceSBarry Smith    positive parameter delta.
36349b94acceSBarry Smith 
36359b94acceSBarry Smith     Input Parameters:
3636c7afd0dbSLois Curfman McInnes +   snes - the SNES context
36379b94acceSBarry Smith .   y - approximate solution of linear system
36389b94acceSBarry Smith .   fnorm - 2-norm of current function
3639c7afd0dbSLois Curfman McInnes -   delta - trust region size
36409b94acceSBarry Smith 
36419b94acceSBarry Smith     Output Parameters:
3642c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
36439b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
36449b94acceSBarry Smith     region, and exceeds zero otherwise.
3645c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
36469b94acceSBarry Smith 
36479b94acceSBarry Smith     Note:
364804d7464bSBarry Smith     For non-trust region methods such as SNESNEWTONLS, the parameter delta
36499b94acceSBarry Smith     is set to be the maximum allowable step size.
36509b94acceSBarry Smith 
36519b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
36529b94acceSBarry Smith */
3653dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
36549b94acceSBarry Smith {
3655064f8208SBarry Smith   PetscReal      nrm;
3656ea709b57SSatish Balay   PetscScalar    cnorm;
3657dfbe8321SBarry Smith   PetscErrorCode ierr;
36583a40ed3dSBarry Smith 
36593a40ed3dSBarry Smith   PetscFunctionBegin;
36600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36610700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3662c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3663184914b5SBarry Smith 
3664064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3665064f8208SBarry Smith   if (nrm > *delta) {
3666064f8208SBarry Smith     nrm     = *delta/nrm;
3667064f8208SBarry Smith     *gpnorm = (1.0 - nrm)*(*fnorm);
3668064f8208SBarry Smith     cnorm   = nrm;
36692dcb1b2aSMatthew Knepley     ierr    = VecScale(y,cnorm);CHKERRQ(ierr);
36709b94acceSBarry Smith     *ynorm  = *delta;
36719b94acceSBarry Smith   } else {
36729b94acceSBarry Smith     *gpnorm = 0.0;
3673064f8208SBarry Smith     *ynorm  = nrm;
36749b94acceSBarry Smith   }
36753a40ed3dSBarry Smith   PetscFunctionReturn(0);
36769b94acceSBarry Smith }
36779b94acceSBarry Smith 
36784a2ae208SSatish Balay #undef __FUNCT__
36792a359c20SBarry Smith #define __FUNCT__ "SNESReasonView"
36802a359c20SBarry Smith /*@
36812a359c20SBarry Smith    SNESReasonView - Displays the reason a SNES solve converged or diverged to a viewer
36822a359c20SBarry Smith 
36832a359c20SBarry Smith    Collective on SNES
36842a359c20SBarry Smith 
36852a359c20SBarry Smith    Parameter:
36862a359c20SBarry Smith +  snes - iterative context obtained from SNESCreate()
36872a359c20SBarry Smith -  viewer - the viewer to display the reason
36882a359c20SBarry Smith 
36892a359c20SBarry Smith 
36902a359c20SBarry Smith    Options Database Keys:
36912a359c20SBarry Smith .  -snes_converged_reason - print reason for converged or diverged, also prints number of iterations
36922a359c20SBarry Smith 
36932a359c20SBarry Smith    Level: beginner
36942a359c20SBarry Smith 
36952a359c20SBarry Smith .keywords: SNES, solve, linear system
36962a359c20SBarry Smith 
36972a359c20SBarry Smith .seealso: SNESCreate(), SNESSetUp(), SNESDestroy(), SNESSetTolerances(), SNESConvergedDefault()
36982a359c20SBarry Smith 
36992a359c20SBarry Smith @*/
37002a359c20SBarry Smith PetscErrorCode  SNESReasonView(SNES snes,PetscViewer viewer)
37012a359c20SBarry Smith {
37022a359c20SBarry Smith   PetscErrorCode ierr;
37032a359c20SBarry Smith   PetscBool      isAscii;
37042a359c20SBarry Smith 
37052a359c20SBarry Smith   PetscFunctionBegin;
37062a359c20SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii);CHKERRQ(ierr);
37072a359c20SBarry Smith   if (isAscii) {
37082a359c20SBarry Smith     ierr = PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
37092a359c20SBarry Smith     if (snes->reason > 0) {
37102a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
37112a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %D\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
37122a359c20SBarry Smith       } else {
37132a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
37142a359c20SBarry Smith       }
37152a359c20SBarry Smith     } else {
37162a359c20SBarry Smith       if (((PetscObject) snes)->prefix) {
37172a359c20SBarry 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);
37182a359c20SBarry Smith       } else {
37192a359c20SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
37202a359c20SBarry Smith       }
37212a359c20SBarry Smith     }
37222a359c20SBarry Smith     ierr = PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel);CHKERRQ(ierr);
37232a359c20SBarry Smith   }
37242a359c20SBarry Smith   PetscFunctionReturn(0);
37252a359c20SBarry Smith }
37262a359c20SBarry Smith 
37272a359c20SBarry Smith #undef __FUNCT__
37282a359c20SBarry Smith #define __FUNCT__ "SNESReasonViewFromOptions"
37292a359c20SBarry Smith /*@C
37302a359c20SBarry Smith   SNESReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed.
37312a359c20SBarry Smith 
37322a359c20SBarry Smith   Collective on SNES
37332a359c20SBarry Smith 
37342a359c20SBarry Smith   Input Parameters:
37352a359c20SBarry Smith . snes   - the SNES object
37362a359c20SBarry Smith 
37372a359c20SBarry Smith   Level: intermediate
37382a359c20SBarry Smith 
37392a359c20SBarry Smith @*/
37402a359c20SBarry Smith PetscErrorCode SNESReasonViewFromOptions(SNES snes)
37412a359c20SBarry Smith {
37422a359c20SBarry Smith   PetscErrorCode    ierr;
37432a359c20SBarry Smith   PetscViewer       viewer;
37442a359c20SBarry Smith   PetscBool         flg;
37452a359c20SBarry Smith   static PetscBool  incall = PETSC_FALSE;
37462a359c20SBarry Smith   PetscViewerFormat format;
37472a359c20SBarry Smith 
37482a359c20SBarry Smith   PetscFunctionBegin;
37492a359c20SBarry Smith   if (incall) PetscFunctionReturn(0);
37502a359c20SBarry Smith   incall = PETSC_TRUE;
37512a359c20SBarry Smith   ierr   = PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg);CHKERRQ(ierr);
37522a359c20SBarry Smith   if (flg) {
37532a359c20SBarry Smith     ierr = PetscViewerPushFormat(viewer,format);CHKERRQ(ierr);
37542a359c20SBarry Smith     ierr = SNESReasonView(snes,viewer);CHKERRQ(ierr);
37552a359c20SBarry Smith     ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr);
37562a359c20SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
37572a359c20SBarry Smith   }
37582a359c20SBarry Smith   incall = PETSC_FALSE;
37592a359c20SBarry Smith   PetscFunctionReturn(0);
37602a359c20SBarry Smith }
37612a359c20SBarry Smith 
37622a359c20SBarry Smith #undef __FUNCT__
37634a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
37646ce558aeSBarry Smith /*@C
3765f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3766f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
37679b94acceSBarry Smith 
3768c7afd0dbSLois Curfman McInnes    Collective on SNES
3769c7afd0dbSLois Curfman McInnes 
3770b2002411SLois Curfman McInnes    Input Parameters:
3771c7afd0dbSLois Curfman McInnes +  snes - the SNES context
37720298fd71SBarry Smith .  b - the constant part of the equation F(x) = b, or NULL to use zero.
377385385478SLisandro Dalcin -  x - the solution vector.
37749b94acceSBarry Smith 
3775b2002411SLois Curfman McInnes    Notes:
37768ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
37778ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
37788ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
37798ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
37808ddd3da0SLois Curfman McInnes 
378136851e7fSLois Curfman McInnes    Level: beginner
378236851e7fSLois Curfman McInnes 
37839b94acceSBarry Smith .keywords: SNES, nonlinear, solve
37849b94acceSBarry Smith 
3785c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
37869b94acceSBarry Smith @*/
37877087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
37889b94acceSBarry Smith {
3789dfbe8321SBarry Smith   PetscErrorCode    ierr;
3790ace3abfcSBarry Smith   PetscBool         flg;
3791efd51863SBarry Smith   PetscInt          grid;
37920298fd71SBarry Smith   Vec               xcreated = NULL;
3793caa4e7f2SJed Brown   DM                dm;
3794052efed2SBarry Smith 
37953a40ed3dSBarry Smith   PetscFunctionBegin;
37960700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3797a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3798a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
37990700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
380085385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
380185385478SLisandro Dalcin 
3802caa4e7f2SJed Brown   if (!x) {
3803caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3804caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3805a69afd8bSBarry Smith     x    = xcreated;
3806a69afd8bSBarry Smith   }
3807ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view_pre");CHKERRQ(ierr);
3808f05ece33SBarry Smith 
3809ce94432eSBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);}
3810efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3811efd51863SBarry Smith 
381285385478SLisandro Dalcin     /* set solution vector */
3813efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
38146bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
381585385478SLisandro Dalcin     snes->vec_sol = x;
3816caa4e7f2SJed Brown     ierr          = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3817caa4e7f2SJed Brown 
3818caa4e7f2SJed Brown     /* set affine vector if provided */
381985385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
38206bf464f9SBarry Smith     ierr          = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
382185385478SLisandro Dalcin     snes->vec_rhs = b;
382285385478SLisandro Dalcin 
3823154060b5SMatthew G. Knepley     if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
3824154060b5SMatthew 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");
3825154060b5SMatthew G. Knepley     if (!snes->vec_sol_update /* && snes->vec_sol */) {
3826154060b5SMatthew G. Knepley       ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
3827154060b5SMatthew G. Knepley       ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update);CHKERRQ(ierr);
3828154060b5SMatthew G. Knepley     }
3829154060b5SMatthew G. Knepley     ierr = DMShellSetGlobalVector(dm,snes->vec_sol);CHKERRQ(ierr);
383070e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
38313f149594SLisandro Dalcin 
38327eee914bSBarry Smith     if (!grid) {
38337eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3834d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3835d25893d9SBarry Smith       }
3836dd568438SSatish Balay     }
3837d25893d9SBarry Smith 
3838abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
3839971e163fSPeter Brune     if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;}
3840d5e45103SBarry Smith 
38413f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
38424936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
384385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
38444936397dSBarry Smith     if (snes->domainerror) {
38454936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
38464936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
38474936397dSBarry Smith     }
384817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
38493f149594SLisandro Dalcin 
385037ec4e1aSPeter Brune     if (snes->lagjac_persist) snes->jac_iter += snes->iter;
385137ec4e1aSPeter Brune     if (snes->lagpre_persist) snes->pre_iter += snes->iter;
385237ec4e1aSPeter Brune 
385390d69ab7SBarry Smith     flg  = PETSC_FALSE;
38540298fd71SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,NULL);CHKERRQ(ierr);
3855da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
38562a359c20SBarry Smith     ierr = SNESReasonViewFromOptions(snes);CHKERRQ(ierr);
38575968eb51SBarry Smith 
3858ce94432eSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3859efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3860efd51863SBarry Smith       DM  fine;
3861efd51863SBarry Smith       Vec xnew;
3862efd51863SBarry Smith       Mat interp;
3863efd51863SBarry Smith 
3864ce94432eSBarry Smith       ierr = DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine);CHKERRQ(ierr);
3865ce94432eSBarry Smith       if (!fine) SETERRQ(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
38660298fd71SBarry Smith       ierr = DMCreateInterpolation(snes->dm,fine,&interp,NULL);CHKERRQ(ierr);
3867efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3868efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3869c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3870efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3871efd51863SBarry Smith       x    = xnew;
3872efd51863SBarry Smith 
3873efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3874efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3875efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3876ce94432eSBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)));CHKERRQ(ierr);
3877efd51863SBarry Smith     }
3878efd51863SBarry Smith   }
3879ce1779c8SBarry Smith   ierr = SNESViewFromOptions(snes,NULL,"-snes_view");CHKERRQ(ierr);
3880146574abSBarry Smith   ierr = VecViewFromOptions(snes->vec_sol,((PetscObject)snes)->prefix,"-snes_view_solution");CHKERRQ(ierr);
38813f7e2da0SPeter Brune 
3882a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
3883e04113cfSBarry Smith   ierr = PetscObjectSAWsBlock((PetscObject)snes);CHKERRQ(ierr);
38843a40ed3dSBarry Smith   PetscFunctionReturn(0);
38859b94acceSBarry Smith }
38869b94acceSBarry Smith 
38879b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
38889b94acceSBarry Smith 
38894a2ae208SSatish Balay #undef __FUNCT__
38904a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
389182bf6240SBarry Smith /*@C
38924b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
38939b94acceSBarry Smith 
3894fee21e36SBarry Smith    Collective on SNES
3895fee21e36SBarry Smith 
3896c7afd0dbSLois Curfman McInnes    Input Parameters:
3897c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3898454a90a3SBarry Smith -  type - a known method
3899c7afd0dbSLois Curfman McInnes 
3900c7afd0dbSLois Curfman McInnes    Options Database Key:
3901454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
390204d7464bSBarry Smith    of available methods (for instance, newtonls or newtontr)
3903ae12b187SLois Curfman McInnes 
39049b94acceSBarry Smith    Notes:
3905e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
390604d7464bSBarry Smith +    SNESNEWTONLS - Newton's method with line search
3907c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
390804d7464bSBarry Smith .    SNESNEWTONTR - Newton's method with trust region
3909c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
39109b94acceSBarry Smith 
3911ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3912ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3913ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3914ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3915ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3916ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3917ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3918ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3919ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3920b0a32e0cSBarry Smith   appropriate method.
392136851e7fSLois Curfman McInnes 
39228f6c3df8SBarry Smith     Developer Notes: SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates
39238f6c3df8SBarry Smith     the constructor in that list and calls it to create the spexific object.
39248f6c3df8SBarry Smith 
392536851e7fSLois Curfman McInnes   Level: intermediate
3926a703fe33SLois Curfman McInnes 
3927454a90a3SBarry Smith .keywords: SNES, set, type
3928435da068SBarry Smith 
39298f6c3df8SBarry Smith .seealso: SNESType, SNESCreate(), SNESDestroy(), SNESGetType(), SNESSetFromOptions()
3930435da068SBarry Smith 
39319b94acceSBarry Smith @*/
393219fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
39339b94acceSBarry Smith {
3934dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3935ace3abfcSBarry Smith   PetscBool      match;
39363a40ed3dSBarry Smith 
39373a40ed3dSBarry Smith   PetscFunctionBegin;
39380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39394482741eSBarry Smith   PetscValidCharPointer(type,2);
394082bf6240SBarry Smith 
3941251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
39420f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
394392ff6ae8SBarry Smith 
39441c9cd337SJed Brown   ierr =  PetscFunctionListFind(SNESList,type,&r);CHKERRQ(ierr);
3945e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
394675396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3947b5c23020SJed Brown   if (snes->ops->destroy) {
3948b5c23020SJed Brown     ierr               = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
39490298fd71SBarry Smith     snes->ops->destroy = NULL;
3950b5c23020SJed Brown   }
395175396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
395275396ef9SLisandro Dalcin   snes->ops->setup          = 0;
395375396ef9SLisandro Dalcin   snes->ops->solve          = 0;
395475396ef9SLisandro Dalcin   snes->ops->view           = 0;
395575396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
395675396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
395775396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
395875396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3959f5af7f23SKarl Rupp 
3960454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
396103bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
39623a40ed3dSBarry Smith   PetscFunctionReturn(0);
39639b94acceSBarry Smith }
39649b94acceSBarry Smith 
39654a2ae208SSatish Balay #undef __FUNCT__
39664a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
39679b94acceSBarry Smith /*@C
39689a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
39699b94acceSBarry Smith 
3970c7afd0dbSLois Curfman McInnes    Not Collective
3971c7afd0dbSLois Curfman McInnes 
39729b94acceSBarry Smith    Input Parameter:
39734b0e389bSBarry Smith .  snes - nonlinear solver context
39749b94acceSBarry Smith 
39759b94acceSBarry Smith    Output Parameter:
39763a7fca6bSBarry Smith .  type - SNES method (a character string)
39779b94acceSBarry Smith 
397836851e7fSLois Curfman McInnes    Level: intermediate
397936851e7fSLois Curfman McInnes 
3980454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
39819b94acceSBarry Smith @*/
398219fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
39839b94acceSBarry Smith {
39843a40ed3dSBarry Smith   PetscFunctionBegin;
39850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39864482741eSBarry Smith   PetscValidPointer(type,2);
39877adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
39883a40ed3dSBarry Smith   PetscFunctionReturn(0);
39899b94acceSBarry Smith }
39909b94acceSBarry Smith 
39914a2ae208SSatish Balay #undef __FUNCT__
39923cd8a7caSMatthew G. Knepley #define __FUNCT__ "SNESSetSolution"
39933cd8a7caSMatthew G. Knepley /*@
39943cd8a7caSMatthew G. Knepley   SNESSetSolution - Sets the solution vector for use by the SNES routines.
39953cd8a7caSMatthew G. Knepley 
39963cd8a7caSMatthew G. Knepley   Logically Collective on SNES and Vec
39973cd8a7caSMatthew G. Knepley 
39983cd8a7caSMatthew G. Knepley   Input Parameters:
39993cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate()
40003cd8a7caSMatthew G. Knepley - u    - the solution vector
40013cd8a7caSMatthew G. Knepley 
40023cd8a7caSMatthew G. Knepley   Level: beginner
40033cd8a7caSMatthew G. Knepley 
40043cd8a7caSMatthew G. Knepley .keywords: SNES, set, solution
40053cd8a7caSMatthew G. Knepley @*/
40063cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u)
40073cd8a7caSMatthew G. Knepley {
40083cd8a7caSMatthew G. Knepley   DM             dm;
40093cd8a7caSMatthew G. Knepley   PetscErrorCode ierr;
40103cd8a7caSMatthew G. Knepley 
40113cd8a7caSMatthew G. Knepley   PetscFunctionBegin;
40123cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
40133cd8a7caSMatthew G. Knepley   PetscValidHeaderSpecific(u, VEC_CLASSID, 2);
40143cd8a7caSMatthew G. Knepley   ierr = PetscObjectReference((PetscObject) u);CHKERRQ(ierr);
40153cd8a7caSMatthew G. Knepley   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
40163cd8a7caSMatthew G. Knepley 
40173cd8a7caSMatthew G. Knepley   snes->vec_sol = u;
40183cd8a7caSMatthew G. Knepley 
40193cd8a7caSMatthew G. Knepley   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
40203cd8a7caSMatthew G. Knepley   ierr = DMShellSetGlobalVector(dm, u);CHKERRQ(ierr);
40213cd8a7caSMatthew G. Knepley   PetscFunctionReturn(0);
40223cd8a7caSMatthew G. Knepley }
40233cd8a7caSMatthew G. Knepley 
40243cd8a7caSMatthew G. Knepley #undef __FUNCT__
40254a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
402652baeb72SSatish Balay /*@
40279b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
4028c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
40299b94acceSBarry Smith 
4030c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4031c7afd0dbSLois Curfman McInnes 
40329b94acceSBarry Smith    Input Parameter:
40339b94acceSBarry Smith .  snes - the SNES context
40349b94acceSBarry Smith 
40359b94acceSBarry Smith    Output Parameter:
40369b94acceSBarry Smith .  x - the solution
40379b94acceSBarry Smith 
403870e92668SMatthew Knepley    Level: intermediate
403936851e7fSLois Curfman McInnes 
40409b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
40419b94acceSBarry Smith 
404285385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
40439b94acceSBarry Smith @*/
40447087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
40459b94acceSBarry Smith {
40463a40ed3dSBarry Smith   PetscFunctionBegin;
40470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40484482741eSBarry Smith   PetscValidPointer(x,2);
404985385478SLisandro Dalcin   *x = snes->vec_sol;
405070e92668SMatthew Knepley   PetscFunctionReturn(0);
405170e92668SMatthew Knepley }
405270e92668SMatthew Knepley 
405370e92668SMatthew Knepley #undef __FUNCT__
40544a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
405552baeb72SSatish Balay /*@
40569b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
40579b94acceSBarry Smith    stored.
40589b94acceSBarry Smith 
4059c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
4060c7afd0dbSLois Curfman McInnes 
40619b94acceSBarry Smith    Input Parameter:
40629b94acceSBarry Smith .  snes - the SNES context
40639b94acceSBarry Smith 
40649b94acceSBarry Smith    Output Parameter:
40659b94acceSBarry Smith .  x - the solution update
40669b94acceSBarry Smith 
406736851e7fSLois Curfman McInnes    Level: advanced
406836851e7fSLois Curfman McInnes 
40699b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
40709b94acceSBarry Smith 
407185385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
40729b94acceSBarry Smith @*/
40737087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
40749b94acceSBarry Smith {
40753a40ed3dSBarry Smith   PetscFunctionBegin;
40760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40774482741eSBarry Smith   PetscValidPointer(x,2);
407885385478SLisandro Dalcin   *x = snes->vec_sol_update;
40793a40ed3dSBarry Smith   PetscFunctionReturn(0);
40809b94acceSBarry Smith }
40819b94acceSBarry Smith 
40824a2ae208SSatish Balay #undef __FUNCT__
40834a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
40849b94acceSBarry Smith /*@C
40853638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
40869b94acceSBarry Smith 
4087a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
4088c7afd0dbSLois Curfman McInnes 
40899b94acceSBarry Smith    Input Parameter:
40909b94acceSBarry Smith .  snes - the SNES context
40919b94acceSBarry Smith 
40929b94acceSBarry Smith    Output Parameter:
40930298fd71SBarry Smith +  r - the vector that is used to store residuals (or NULL if you don't want it)
4094f8b49ee9SBarry Smith .  f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details
40950298fd71SBarry Smith -  ctx - the function context (or NULL if you don't want it)
40969b94acceSBarry Smith 
409736851e7fSLois Curfman McInnes    Level: advanced
409836851e7fSLois Curfman McInnes 
4099a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
41009b94acceSBarry Smith 
4101bf388a1fSBarry Smith .seealso: SNESSetFunction(), SNESGetSolution(), SNESFunction
41029b94acceSBarry Smith @*/
4103f8b49ee9SBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx)
41049b94acceSBarry Smith {
4105a63bb30eSJed Brown   PetscErrorCode ierr;
41066cab3a1bSJed Brown   DM             dm;
4107a63bb30eSJed Brown 
41083a40ed3dSBarry Smith   PetscFunctionBegin;
41090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4110a63bb30eSJed Brown   if (r) {
4111a63bb30eSJed Brown     if (!snes->vec_func) {
4112a63bb30eSJed Brown       if (snes->vec_rhs) {
4113a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
4114a63bb30eSJed Brown       } else if (snes->vec_sol) {
4115a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
4116a63bb30eSJed Brown       } else if (snes->dm) {
4117a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
4118a63bb30eSJed Brown       }
4119a63bb30eSJed Brown     }
4120a63bb30eSJed Brown     *r = snes->vec_func;
4121a63bb30eSJed Brown   }
41226cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4123f8b49ee9SBarry Smith   ierr = DMSNESGetFunction(dm,f,ctx);CHKERRQ(ierr);
41243a40ed3dSBarry Smith   PetscFunctionReturn(0);
41259b94acceSBarry Smith }
41269b94acceSBarry Smith 
4127c79ef259SPeter Brune /*@C
4128be95d8f1SBarry Smith    SNESGetNGS - Returns the NGS function and context.
4129c79ef259SPeter Brune 
4130c79ef259SPeter Brune    Input Parameter:
4131c79ef259SPeter Brune .  snes - the SNES context
4132c79ef259SPeter Brune 
4133c79ef259SPeter Brune    Output Parameter:
4134be95d8f1SBarry Smith +  f - the function (or NULL) see SNESNGSFunction for details
41350298fd71SBarry Smith -  ctx    - the function context (or NULL)
4136c79ef259SPeter Brune 
4137c79ef259SPeter Brune    Level: advanced
4138c79ef259SPeter Brune 
4139c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
4140c79ef259SPeter Brune 
4141be95d8f1SBarry Smith .seealso: SNESSetNGS(), SNESGetFunction()
4142c79ef259SPeter Brune @*/
4143c79ef259SPeter Brune 
41444a2ae208SSatish Balay #undef __FUNCT__
4145be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNGS"
4146be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx)
4147646217ecSPeter Brune {
41486cab3a1bSJed Brown   PetscErrorCode ierr;
41496cab3a1bSJed Brown   DM             dm;
41506cab3a1bSJed Brown 
4151646217ecSPeter Brune   PetscFunctionBegin;
4152646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41536cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
4154be95d8f1SBarry Smith   ierr = DMSNESGetNGS(dm,f,ctx);CHKERRQ(ierr);
4155646217ecSPeter Brune   PetscFunctionReturn(0);
4156646217ecSPeter Brune }
4157646217ecSPeter Brune 
41584a2ae208SSatish Balay #undef __FUNCT__
41594a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
41603c7409f5SSatish Balay /*@C
41613c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
4162d850072dSLois Curfman McInnes    SNES options in the database.
41633c7409f5SSatish Balay 
41643f9fe445SBarry Smith    Logically Collective on SNES
4165fee21e36SBarry Smith 
4166c7afd0dbSLois Curfman McInnes    Input Parameter:
4167c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4168c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4169c7afd0dbSLois Curfman McInnes 
4170d850072dSLois Curfman McInnes    Notes:
4171a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4172c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4173d850072dSLois Curfman McInnes 
417436851e7fSLois Curfman McInnes    Level: advanced
417536851e7fSLois Curfman McInnes 
41763c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
4177a86d99e1SLois Curfman McInnes 
4178a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
41793c7409f5SSatish Balay @*/
41807087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
41813c7409f5SSatish Balay {
4182dfbe8321SBarry Smith   PetscErrorCode ierr;
41833c7409f5SSatish Balay 
41843a40ed3dSBarry Smith   PetscFunctionBegin;
41850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4186639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
41871cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
418835f5d045SPeter Brune   if (snes->linesearch) {
41897601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
419008b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
419135f5d045SPeter Brune   }
419235f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
41933a40ed3dSBarry Smith   PetscFunctionReturn(0);
41943c7409f5SSatish Balay }
41953c7409f5SSatish Balay 
41964a2ae208SSatish Balay #undef __FUNCT__
41974a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
41983c7409f5SSatish Balay /*@C
4199f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4200d850072dSLois Curfman McInnes    SNES options in the database.
42013c7409f5SSatish Balay 
42023f9fe445SBarry Smith    Logically Collective on SNES
4203fee21e36SBarry Smith 
4204c7afd0dbSLois Curfman McInnes    Input Parameters:
4205c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4206c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4207c7afd0dbSLois Curfman McInnes 
4208d850072dSLois Curfman McInnes    Notes:
4209a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4210c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4211d850072dSLois Curfman McInnes 
421236851e7fSLois Curfman McInnes    Level: advanced
421336851e7fSLois Curfman McInnes 
42143c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
4215a86d99e1SLois Curfman McInnes 
4216a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
42173c7409f5SSatish Balay @*/
42187087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
42193c7409f5SSatish Balay {
4220dfbe8321SBarry Smith   PetscErrorCode ierr;
42213c7409f5SSatish Balay 
42223a40ed3dSBarry Smith   PetscFunctionBegin;
42230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4224639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
42251cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
422635f5d045SPeter Brune   if (snes->linesearch) {
42277601faf0SJed Brown     ierr = SNESGetLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
422808b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
422935f5d045SPeter Brune   }
423035f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
42313a40ed3dSBarry Smith   PetscFunctionReturn(0);
42323c7409f5SSatish Balay }
42333c7409f5SSatish Balay 
42344a2ae208SSatish Balay #undef __FUNCT__
42354a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
42369ab63eb5SSatish Balay /*@C
42373c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
42383c7409f5SSatish Balay    SNES options in the database.
42393c7409f5SSatish Balay 
4240c7afd0dbSLois Curfman McInnes    Not Collective
4241c7afd0dbSLois Curfman McInnes 
42423c7409f5SSatish Balay    Input Parameter:
42433c7409f5SSatish Balay .  snes - the SNES context
42443c7409f5SSatish Balay 
42453c7409f5SSatish Balay    Output Parameter:
42463c7409f5SSatish Balay .  prefix - pointer to the prefix string used
42473c7409f5SSatish Balay 
42484ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
42499ab63eb5SSatish Balay    sufficient length to hold the prefix.
42509ab63eb5SSatish Balay 
425136851e7fSLois Curfman McInnes    Level: advanced
425236851e7fSLois Curfman McInnes 
42533c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4254a86d99e1SLois Curfman McInnes 
4255a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
42563c7409f5SSatish Balay @*/
42577087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
42583c7409f5SSatish Balay {
4259dfbe8321SBarry Smith   PetscErrorCode ierr;
42603c7409f5SSatish Balay 
42613a40ed3dSBarry Smith   PetscFunctionBegin;
42620700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4263639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
42643a40ed3dSBarry Smith   PetscFunctionReturn(0);
42653c7409f5SSatish Balay }
42663c7409f5SSatish Balay 
4267b2002411SLois Curfman McInnes 
42684a2ae208SSatish Balay #undef __FUNCT__
42694a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
42703cea93caSBarry Smith /*@C
42711c84c290SBarry Smith   SNESRegister - Adds a method to the nonlinear solver package.
42721c84c290SBarry Smith 
42731c84c290SBarry Smith    Not collective
42741c84c290SBarry Smith 
42751c84c290SBarry Smith    Input Parameters:
42761c84c290SBarry Smith +  name_solver - name of a new user-defined solver
42771c84c290SBarry Smith -  routine_create - routine to create method context
42781c84c290SBarry Smith 
42791c84c290SBarry Smith    Notes:
42801c84c290SBarry Smith    SNESRegister() may be called multiple times to add several user-defined solvers.
42811c84c290SBarry Smith 
42821c84c290SBarry Smith    Sample usage:
42831c84c290SBarry Smith .vb
4284bdf89e91SBarry Smith    SNESRegister("my_solver",MySolverCreate);
42851c84c290SBarry Smith .ve
42861c84c290SBarry Smith 
42871c84c290SBarry Smith    Then, your solver can be chosen with the procedural interface via
42881c84c290SBarry Smith $     SNESSetType(snes,"my_solver")
42891c84c290SBarry Smith    or at runtime via the option
42901c84c290SBarry Smith $     -snes_type my_solver
42911c84c290SBarry Smith 
42921c84c290SBarry Smith    Level: advanced
42931c84c290SBarry Smith 
42941c84c290SBarry Smith     Note: If your function is not being put into a shared library then use SNESRegister() instead
42951c84c290SBarry Smith 
42961c84c290SBarry Smith .keywords: SNES, nonlinear, register
42971c84c290SBarry Smith 
42981c84c290SBarry Smith .seealso: SNESRegisterAll(), SNESRegisterDestroy()
42993cea93caSBarry Smith 
43007f6c08e0SMatthew Knepley   Level: advanced
43013cea93caSBarry Smith @*/
4302bdf89e91SBarry Smith PetscErrorCode  SNESRegister(const char sname[],PetscErrorCode (*function)(SNES))
4303b2002411SLois Curfman McInnes {
4304dfbe8321SBarry Smith   PetscErrorCode ierr;
4305b2002411SLois Curfman McInnes 
4306b2002411SLois Curfman McInnes   PetscFunctionBegin;
4307a240a19fSJed Brown   ierr = PetscFunctionListAdd(&SNESList,sname,function);CHKERRQ(ierr);
4308b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4309b2002411SLois Curfman McInnes }
4310da9b6338SBarry Smith 
4311da9b6338SBarry Smith #undef __FUNCT__
4312da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
43137087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4314da9b6338SBarry Smith {
4315dfbe8321SBarry Smith   PetscErrorCode ierr;
431677431f27SBarry Smith   PetscInt       N,i,j;
4317da9b6338SBarry Smith   Vec            u,uh,fh;
4318da9b6338SBarry Smith   PetscScalar    value;
4319da9b6338SBarry Smith   PetscReal      norm;
4320da9b6338SBarry Smith 
4321da9b6338SBarry Smith   PetscFunctionBegin;
4322da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4323da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4324da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4325da9b6338SBarry Smith 
4326da9b6338SBarry Smith   /* currently only works for sequential */
432722d28d08SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");CHKERRQ(ierr);
4328da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4329da9b6338SBarry Smith   for (i=0; i<N; i++) {
4330da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
433177431f27SBarry Smith     ierr = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4332da9b6338SBarry Smith     for (j=-10; j<11; j++) {
43338b49ba18SBarry Smith       value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0);
4334da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
43353ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4336da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
433777431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4338da9b6338SBarry Smith       value = -value;
4339da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4340da9b6338SBarry Smith     }
4341da9b6338SBarry Smith   }
43426bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
43436bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4344da9b6338SBarry Smith   PetscFunctionReturn(0);
4345da9b6338SBarry Smith }
434671f87433Sdalcinl 
434771f87433Sdalcinl #undef __FUNCT__
4348fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
434971f87433Sdalcinl /*@
4350fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
435171f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
435271f87433Sdalcinl    Newton method.
435371f87433Sdalcinl 
43543f9fe445SBarry Smith    Logically Collective on SNES
435571f87433Sdalcinl 
435671f87433Sdalcinl    Input Parameters:
435771f87433Sdalcinl +  snes - SNES context
435871f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
435971f87433Sdalcinl 
436064ba62caSBarry Smith     Options Database:
436164ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
436264ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
436364ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
436464ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
436564ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
436664ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
436764ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
436864ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
436964ba62caSBarry Smith 
437071f87433Sdalcinl    Notes:
437171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
437271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
437371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
437471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
437571f87433Sdalcinl    solver.
437671f87433Sdalcinl 
437771f87433Sdalcinl    Level: advanced
437871f87433Sdalcinl 
437971f87433Sdalcinl    Reference:
438071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
438171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
438271f87433Sdalcinl 
438371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
438471f87433Sdalcinl 
4385fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
438671f87433Sdalcinl @*/
43877087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool flag)
438871f87433Sdalcinl {
438971f87433Sdalcinl   PetscFunctionBegin;
43900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4391acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
439271f87433Sdalcinl   snes->ksp_ewconv = flag;
439371f87433Sdalcinl   PetscFunctionReturn(0);
439471f87433Sdalcinl }
439571f87433Sdalcinl 
439671f87433Sdalcinl #undef __FUNCT__
4397fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
439871f87433Sdalcinl /*@
4399fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
440071f87433Sdalcinl    for computing relative tolerance for linear solvers within an
440171f87433Sdalcinl    inexact Newton method.
440271f87433Sdalcinl 
440371f87433Sdalcinl    Not Collective
440471f87433Sdalcinl 
440571f87433Sdalcinl    Input Parameter:
440671f87433Sdalcinl .  snes - SNES context
440771f87433Sdalcinl 
440871f87433Sdalcinl    Output Parameter:
440971f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
441071f87433Sdalcinl 
441171f87433Sdalcinl    Notes:
441271f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
441371f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
441471f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
441571f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
441671f87433Sdalcinl    solver.
441771f87433Sdalcinl 
441871f87433Sdalcinl    Level: advanced
441971f87433Sdalcinl 
442071f87433Sdalcinl    Reference:
442171f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
442271f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
442371f87433Sdalcinl 
442471f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
442571f87433Sdalcinl 
4426fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
442771f87433Sdalcinl @*/
44287087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
442971f87433Sdalcinl {
443071f87433Sdalcinl   PetscFunctionBegin;
44310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
443271f87433Sdalcinl   PetscValidPointer(flag,2);
443371f87433Sdalcinl   *flag = snes->ksp_ewconv;
443471f87433Sdalcinl   PetscFunctionReturn(0);
443571f87433Sdalcinl }
443671f87433Sdalcinl 
443771f87433Sdalcinl #undef __FUNCT__
4438fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
443971f87433Sdalcinl /*@
4440fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
444171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
444271f87433Sdalcinl    Newton method.
444371f87433Sdalcinl 
44443f9fe445SBarry Smith    Logically Collective on SNES
444571f87433Sdalcinl 
444671f87433Sdalcinl    Input Parameters:
444771f87433Sdalcinl +    snes - SNES context
444871f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
444971f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
445071f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
445171f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
445271f87433Sdalcinl              (0 <= gamma2 <= 1)
445371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
445471f87433Sdalcinl .    alpha2 - power for safeguard
445571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
445671f87433Sdalcinl 
445771f87433Sdalcinl    Note:
445871f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
445971f87433Sdalcinl 
446071f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
446171f87433Sdalcinl 
446271f87433Sdalcinl    Level: advanced
446371f87433Sdalcinl 
446471f87433Sdalcinl    Reference:
446571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
446671f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
446771f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
446871f87433Sdalcinl 
446971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
447071f87433Sdalcinl 
4471fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
447271f87433Sdalcinl @*/
4473f5af7f23SKarl Rupp PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
447471f87433Sdalcinl {
4475fa9f3622SBarry Smith   SNESKSPEW *kctx;
44765fd66863SKarl Rupp 
447771f87433Sdalcinl   PetscFunctionBegin;
44780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4479fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4480e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4481c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4482c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4483c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4484c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4485c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4486c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4487c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
448871f87433Sdalcinl 
448971f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
449071f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
449171f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
449271f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
449371f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
449471f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
449571f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
449671f87433Sdalcinl 
4497f23aa3ddSBarry 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);
449857622a8eSBarry 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);
449957622a8eSBarry 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);
450057622a8eSBarry 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);
450157622a8eSBarry 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);
450257622a8eSBarry 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);
450371f87433Sdalcinl   PetscFunctionReturn(0);
450471f87433Sdalcinl }
450571f87433Sdalcinl 
450671f87433Sdalcinl #undef __FUNCT__
4507fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
450871f87433Sdalcinl /*@
4509fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
451071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
451171f87433Sdalcinl    Newton method.
451271f87433Sdalcinl 
451371f87433Sdalcinl    Not Collective
451471f87433Sdalcinl 
451571f87433Sdalcinl    Input Parameters:
451671f87433Sdalcinl      snes - SNES context
451771f87433Sdalcinl 
451871f87433Sdalcinl    Output Parameters:
451971f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
452071f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
452171f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
4522bf388a1fSBarry Smith .    gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1)
452371f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
452471f87433Sdalcinl .    alpha2 - power for safeguard
452571f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
452671f87433Sdalcinl 
452771f87433Sdalcinl    Level: advanced
452871f87433Sdalcinl 
452971f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
453071f87433Sdalcinl 
4531fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
453271f87433Sdalcinl @*/
4533bf388a1fSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
453471f87433Sdalcinl {
4535fa9f3622SBarry Smith   SNESKSPEW *kctx;
45365fd66863SKarl Rupp 
453771f87433Sdalcinl   PetscFunctionBegin;
45380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4539fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4540e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
454171f87433Sdalcinl   if (version)   *version   = kctx->version;
454271f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
454371f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
454471f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
454571f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
454671f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
454771f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
454871f87433Sdalcinl   PetscFunctionReturn(0);
454971f87433Sdalcinl }
455071f87433Sdalcinl 
455171f87433Sdalcinl #undef __FUNCT__
4552d5378b5fSDmitry Karpeev #define __FUNCT__ "KSPPreSolve_SNESEW"
4553d5378b5fSDmitry Karpeev  PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
455471f87433Sdalcinl {
455571f87433Sdalcinl   PetscErrorCode ierr;
4556fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
455771f87433Sdalcinl   PetscReal      rtol  = PETSC_DEFAULT,stol;
455871f87433Sdalcinl 
455971f87433Sdalcinl   PetscFunctionBegin;
4560d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
456130058271SDmitry Karpeev   if (!snes->iter) {
456230058271SDmitry Karpeev     rtol = kctx->rtol_0; /* first time in, so use the original user rtol */
456330058271SDmitry Karpeev     ierr = VecNorm(snes->vec_func,NORM_2,&kctx->norm_first);CHKERRQ(ierr);
456430058271SDmitry Karpeev   }
4565f5af7f23SKarl Rupp   else {
456671f87433Sdalcinl     if (kctx->version == 1) {
456771f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
456871f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
456985ec1a3cSBarry Smith       stol = PetscPowReal(kctx->rtol_last,kctx->alpha2);
457071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
457171f87433Sdalcinl     } else if (kctx->version == 2) {
457285ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
457385ec1a3cSBarry Smith       stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha);
457471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
457571f87433Sdalcinl     } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */
457685ec1a3cSBarry Smith       rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha);
457771f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
457885ec1a3cSBarry Smith       stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha);
457971f87433Sdalcinl       stol = PetscMax(rtol,stol);
458071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
458171f87433Sdalcinl       /* safeguard: avoid oversolving */
458230058271SDmitry Karpeev       stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm;
458371f87433Sdalcinl       stol = PetscMax(rtol,stol);
458471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4585e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
458671f87433Sdalcinl   }
458771f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
458871f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
458971f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
459057622a8eSBarry Smith   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol);CHKERRQ(ierr);
459171f87433Sdalcinl   PetscFunctionReturn(0);
459271f87433Sdalcinl }
459371f87433Sdalcinl 
459471f87433Sdalcinl #undef __FUNCT__
4595d5378b5fSDmitry Karpeev #define __FUNCT__ "KSPPostSolve_SNESEW"
4596d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes)
459771f87433Sdalcinl {
459871f87433Sdalcinl   PetscErrorCode ierr;
4599fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
460071f87433Sdalcinl   PCSide         pcside;
460171f87433Sdalcinl   Vec            lres;
460271f87433Sdalcinl 
460371f87433Sdalcinl   PetscFunctionBegin;
4604d4211eb9SBarry Smith   if (!snes->ksp_ewconv) PetscFunctionReturn(0);
460571f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
460671dbe336SPeter Brune   kctx->norm_last = snes->norm;
460771f87433Sdalcinl   if (kctx->version == 1) {
46084f00ce20SMatthew G. Knepley     PC        pc;
46094f00ce20SMatthew G. Knepley     PetscBool isNone;
46104f00ce20SMatthew G. Knepley 
46114f00ce20SMatthew G. Knepley     ierr = KSPGetPC(ksp, &pc);CHKERRQ(ierr);
46124f00ce20SMatthew G. Knepley     ierr = PetscObjectTypeCompare((PetscObject) pc, PCNONE, &isNone);CHKERRQ(ierr);
4613b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
46144f00ce20SMatthew G. Knepley      if (pcside == PC_RIGHT || isNone) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
461571f87433Sdalcinl       /* KSP residual is true linear residual */
461671f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
461771f87433Sdalcinl     } else {
461871f87433Sdalcinl       /* KSP residual is preconditioned residual */
461971f87433Sdalcinl       /* compute true linear residual norm */
462071f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
462171f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
462271f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
462371f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
46246bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
462571f87433Sdalcinl     }
462671f87433Sdalcinl   }
462771f87433Sdalcinl   PetscFunctionReturn(0);
462871f87433Sdalcinl }
462971f87433Sdalcinl 
463071f87433Sdalcinl #undef __FUNCT__
4631d4211eb9SBarry Smith #define __FUNCT__ "SNESGetKSP"
4632d4211eb9SBarry Smith /*@
4633d4211eb9SBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
4634d4211eb9SBarry Smith 
4635d4211eb9SBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
4636d4211eb9SBarry Smith 
4637d4211eb9SBarry Smith    Input Parameter:
4638d4211eb9SBarry Smith .  snes - the SNES context
4639d4211eb9SBarry Smith 
4640d4211eb9SBarry Smith    Output Parameter:
4641d4211eb9SBarry Smith .  ksp - the KSP context
4642d4211eb9SBarry Smith 
4643d4211eb9SBarry Smith    Notes:
4644d4211eb9SBarry Smith    The user can then directly manipulate the KSP context to set various
4645d4211eb9SBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
4646d4211eb9SBarry Smith    PC contexts as well.
4647d4211eb9SBarry Smith 
4648d4211eb9SBarry Smith    Level: beginner
4649d4211eb9SBarry Smith 
4650d4211eb9SBarry Smith .keywords: SNES, nonlinear, get, KSP, context
4651d4211eb9SBarry Smith 
4652d4211eb9SBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
4653d4211eb9SBarry Smith @*/
4654d4211eb9SBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
465571f87433Sdalcinl {
465671f87433Sdalcinl   PetscErrorCode ierr;
465771f87433Sdalcinl 
465871f87433Sdalcinl   PetscFunctionBegin;
4659d4211eb9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4660d4211eb9SBarry Smith   PetscValidPointer(ksp,2);
4661d4211eb9SBarry Smith 
4662d4211eb9SBarry Smith   if (!snes->ksp) {
4663a5c2985bSBarry Smith     PetscBool monitor = PETSC_FALSE;
4664a5c2985bSBarry Smith 
4665d4211eb9SBarry Smith     ierr = KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp);CHKERRQ(ierr);
4666d4211eb9SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
46673bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp);CHKERRQ(ierr);
4668d4211eb9SBarry Smith 
4669d5378b5fSDmitry Karpeev     ierr = KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes);CHKERRQ(ierr);
4670d5378b5fSDmitry Karpeev     ierr = KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes);CHKERRQ(ierr);
4671a5c2985bSBarry Smith 
4672e5f7ee39SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-ksp_monitor_snes",&monitor,NULL);CHKERRQ(ierr);
4673a5c2985bSBarry Smith     if (monitor) {
4674a5c2985bSBarry Smith       ierr = KSPMonitorSet(snes->ksp,KSPMonitorSNES,snes,NULL);CHKERRQ(ierr);
4675a5c2985bSBarry Smith     }
4676e5f7ee39SBarry Smith     monitor = PETSC_FALSE;
4677e5f7ee39SBarry Smith     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-ksp_monitor_snes_lg",&monitor,NULL);CHKERRQ(ierr);
4678e5f7ee39SBarry Smith     if (monitor) {
4679e5f7ee39SBarry Smith       PetscObject *objs;
4680e5f7ee39SBarry Smith       ierr = KSPMonitorSNESLGResidualNormCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,600,600,&objs);CHKERRQ(ierr);
4681e5f7ee39SBarry Smith       objs[0] = (PetscObject) snes;
4682e5f7ee39SBarry Smith       ierr = KSPMonitorSet(snes->ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))KSPMonitorSNESLGResidualNorm,objs,(PetscErrorCode (*)(void**))KSPMonitorSNESLGResidualNormDestroy);CHKERRQ(ierr);
4683e5f7ee39SBarry Smith     }
4684d4211eb9SBarry Smith   }
4685d4211eb9SBarry Smith   *ksp = snes->ksp;
468671f87433Sdalcinl   PetscFunctionReturn(0);
468771f87433Sdalcinl }
46886c699258SBarry Smith 
4689d4211eb9SBarry Smith 
4690b4615a05SBarry Smith #include <petsc-private/dmimpl.h>
46916c699258SBarry Smith #undef __FUNCT__
46926c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
46936c699258SBarry Smith /*@
46946c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
46956c699258SBarry Smith 
46963f9fe445SBarry Smith    Logically Collective on SNES
46976c699258SBarry Smith 
46986c699258SBarry Smith    Input Parameters:
46996c699258SBarry Smith +  snes - the preconditioner context
47006c699258SBarry Smith -  dm - the dm
47016c699258SBarry Smith 
47026c699258SBarry Smith    Level: intermediate
47036c699258SBarry Smith 
47046c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
47056c699258SBarry Smith @*/
47067087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
47076c699258SBarry Smith {
47086c699258SBarry Smith   PetscErrorCode ierr;
4709345fed2cSBarry Smith   KSP            ksp;
4710942e3340SBarry Smith   DMSNES         sdm;
47116c699258SBarry Smith 
47126c699258SBarry Smith   PetscFunctionBegin;
47130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4714d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
4715942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
4716b4615a05SBarry Smith     if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) {
4717942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4718942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
4719f5af7f23SKarl Rupp       if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */
47206cab3a1bSJed Brown     }
47216bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
47226cab3a1bSJed Brown   }
47236c699258SBarry Smith   snes->dm     = dm;
4724116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
4725f5af7f23SKarl Rupp 
4726345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4727345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4728f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
47292c155ee1SBarry Smith   if (snes->pc) {
47302c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4731be95d8f1SBarry Smith     ierr = SNESSetNPCSide(snes,snes->pcside);CHKERRQ(ierr);
47322c155ee1SBarry Smith   }
47336c699258SBarry Smith   PetscFunctionReturn(0);
47346c699258SBarry Smith }
47356c699258SBarry Smith 
47366c699258SBarry Smith #undef __FUNCT__
47376c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
47386c699258SBarry Smith /*@
47396c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
47406c699258SBarry Smith 
47413f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
47426c699258SBarry Smith 
47436c699258SBarry Smith    Input Parameter:
47446c699258SBarry Smith . snes - the preconditioner context
47456c699258SBarry Smith 
47466c699258SBarry Smith    Output Parameter:
47476c699258SBarry Smith .  dm - the dm
47486c699258SBarry Smith 
47496c699258SBarry Smith    Level: intermediate
47506c699258SBarry Smith 
47516c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
47526c699258SBarry Smith @*/
47537087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
47546c699258SBarry Smith {
47556cab3a1bSJed Brown   PetscErrorCode ierr;
47566cab3a1bSJed Brown 
47576c699258SBarry Smith   PetscFunctionBegin;
47580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47596cab3a1bSJed Brown   if (!snes->dm) {
4760ce94432eSBarry Smith     ierr         = DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm);CHKERRQ(ierr);
4761116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
47626cab3a1bSJed Brown   }
47636c699258SBarry Smith   *dm = snes->dm;
47646c699258SBarry Smith   PetscFunctionReturn(0);
47656c699258SBarry Smith }
47660807856dSBarry Smith 
476731823bd8SMatthew G Knepley #undef __FUNCT__
4768be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNPC"
476931823bd8SMatthew G Knepley /*@
4770be95d8f1SBarry Smith   SNESSetNPC - Sets the nonlinear preconditioner to be used.
477131823bd8SMatthew G Knepley 
477231823bd8SMatthew G Knepley   Collective on SNES
477331823bd8SMatthew G Knepley 
477431823bd8SMatthew G Knepley   Input Parameters:
477531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
477631823bd8SMatthew G Knepley - pc   - the preconditioner object
477731823bd8SMatthew G Knepley 
477831823bd8SMatthew G Knepley   Notes:
4779be95d8f1SBarry Smith   Use SNESGetNPC() to retrieve the preconditioner context (for example,
478031823bd8SMatthew G Knepley   to configure it using the API).
478131823bd8SMatthew G Knepley 
478231823bd8SMatthew G Knepley   Level: developer
478331823bd8SMatthew G Knepley 
478431823bd8SMatthew G Knepley .keywords: SNES, set, precondition
47853ad1a0b9SPatrick Farrell .seealso: SNESGetNPC(), SNESHasNPC()
478631823bd8SMatthew G Knepley @*/
4787be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc)
478831823bd8SMatthew G Knepley {
478931823bd8SMatthew G Knepley   PetscErrorCode ierr;
479031823bd8SMatthew G Knepley 
479131823bd8SMatthew G Knepley   PetscFunctionBegin;
479231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
479331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
479431823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
479531823bd8SMatthew G Knepley   ierr     = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4796bf11d3b6SBarry Smith   ierr     = SNESDestroy(&snes->pc);CHKERRQ(ierr);
479731823bd8SMatthew G Knepley   snes->pc = pc;
47983bb1ff40SBarry Smith   ierr     = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->pc);CHKERRQ(ierr);
479931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
480031823bd8SMatthew G Knepley }
480131823bd8SMatthew G Knepley 
480231823bd8SMatthew G Knepley #undef __FUNCT__
4803be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNPC"
480431823bd8SMatthew G Knepley /*@
4805be95d8f1SBarry Smith   SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver.
480631823bd8SMatthew G Knepley 
480731823bd8SMatthew G Knepley   Not Collective
480831823bd8SMatthew G Knepley 
480931823bd8SMatthew G Knepley   Input Parameter:
481031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
481131823bd8SMatthew G Knepley 
481231823bd8SMatthew G Knepley   Output Parameter:
481331823bd8SMatthew G Knepley . pc - preconditioner context
481431823bd8SMatthew G Knepley 
4815be95d8f1SBarry Smith   Notes: If a SNES was previously set with SNESSetNPC() then that SNES is returned.
4816be95d8f1SBarry Smith 
481731823bd8SMatthew G Knepley   Level: developer
481831823bd8SMatthew G Knepley 
481931823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
48203ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESHasNPC()
482131823bd8SMatthew G Knepley @*/
4822be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc)
482331823bd8SMatthew G Knepley {
482431823bd8SMatthew G Knepley   PetscErrorCode ierr;
4825a64e098fSPeter Brune   const char     *optionsprefix;
482631823bd8SMatthew G Knepley 
482731823bd8SMatthew G Knepley   PetscFunctionBegin;
482831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
482931823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
483031823bd8SMatthew G Knepley   if (!snes->pc) {
483182f516ccSBarry Smith     ierr = SNESCreate(PetscObjectComm((PetscObject)snes),&snes->pc);CHKERRQ(ierr);
48324a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
48333bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
4834a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4835a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4836a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
4837971e163fSPeter Brune     ierr = SNESSetCountersReset(snes->pc,PETSC_FALSE);CHKERRQ(ierr);
483831823bd8SMatthew G Knepley   }
483931823bd8SMatthew G Knepley   *pc = snes->pc;
484031823bd8SMatthew G Knepley   PetscFunctionReturn(0);
484131823bd8SMatthew G Knepley }
484231823bd8SMatthew G Knepley 
4843c40d0f55SPeter Brune #undef __FUNCT__
48443ad1a0b9SPatrick Farrell #define __FUNCT__ "SNESHasNPC"
48453ad1a0b9SPatrick Farrell /*@
48463ad1a0b9SPatrick Farrell   SNESHasNPC - Returns whether a nonlinear preconditioner exists
48473ad1a0b9SPatrick Farrell 
48483ad1a0b9SPatrick Farrell   Not Collective
48493ad1a0b9SPatrick Farrell 
48503ad1a0b9SPatrick Farrell   Input Parameter:
48513ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate()
48523ad1a0b9SPatrick Farrell 
48533ad1a0b9SPatrick Farrell   Output Parameter:
48543ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not
48553ad1a0b9SPatrick Farrell 
48563ad1a0b9SPatrick Farrell   Level: developer
48573ad1a0b9SPatrick Farrell 
48583ad1a0b9SPatrick Farrell .keywords: SNES, has, preconditioner
48593ad1a0b9SPatrick Farrell .seealso: SNESSetNPC(), SNESGetNPC()
48603ad1a0b9SPatrick Farrell @*/
48613ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc)
48623ad1a0b9SPatrick Farrell {
48633ad1a0b9SPatrick Farrell   PetscFunctionBegin;
48643ad1a0b9SPatrick Farrell   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
48653ad1a0b9SPatrick Farrell   *has_npc = (PetscBool) (snes->pc != NULL);
48663ad1a0b9SPatrick Farrell   PetscFunctionReturn(0);
48673ad1a0b9SPatrick Farrell }
48683ad1a0b9SPatrick Farrell 
48693ad1a0b9SPatrick Farrell #undef __FUNCT__
4870be95d8f1SBarry Smith #define __FUNCT__ "SNESSetNPCSide"
4871c40d0f55SPeter Brune /*@
4872be95d8f1SBarry Smith     SNESSetNPCSide - Sets the preconditioning side.
4873c40d0f55SPeter Brune 
4874c40d0f55SPeter Brune     Logically Collective on SNES
4875c40d0f55SPeter Brune 
4876c40d0f55SPeter Brune     Input Parameter:
4877c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4878c40d0f55SPeter Brune 
4879c40d0f55SPeter Brune     Output Parameter:
4880c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4881c40d0f55SPeter Brune .vb
4882c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4883c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4884c40d0f55SPeter Brune .ve
4885c40d0f55SPeter Brune 
4886c40d0f55SPeter Brune     Options Database Keys:
4887c40d0f55SPeter Brune .   -snes_pc_side <right,left>
4888c40d0f55SPeter Brune 
4889c40d0f55SPeter Brune     Level: intermediate
4890c40d0f55SPeter Brune 
4891c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
4892c40d0f55SPeter Brune 
4893be95d8f1SBarry Smith .seealso: SNESGetNPCSide(), KSPSetPCSide()
4894c40d0f55SPeter Brune @*/
4895be95d8f1SBarry Smith PetscErrorCode  SNESSetNPCSide(SNES snes,PCSide side)
4896c40d0f55SPeter Brune {
4897c40d0f55SPeter Brune   PetscFunctionBegin;
4898c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4899c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
4900c40d0f55SPeter Brune   snes->pcside = side;
4901c40d0f55SPeter Brune   PetscFunctionReturn(0);
4902c40d0f55SPeter Brune }
4903c40d0f55SPeter Brune 
4904c40d0f55SPeter Brune #undef __FUNCT__
4905be95d8f1SBarry Smith #define __FUNCT__ "SNESGetNPCSide"
4906c40d0f55SPeter Brune /*@
4907be95d8f1SBarry Smith     SNESGetNPCSide - Gets the preconditioning side.
4908c40d0f55SPeter Brune 
4909c40d0f55SPeter Brune     Not Collective
4910c40d0f55SPeter Brune 
4911c40d0f55SPeter Brune     Input Parameter:
4912c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4913c40d0f55SPeter Brune 
4914c40d0f55SPeter Brune     Output Parameter:
4915c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4916c40d0f55SPeter Brune .vb
4917c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4918c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4919c40d0f55SPeter Brune .ve
4920c40d0f55SPeter Brune 
4921c40d0f55SPeter Brune     Level: intermediate
4922c40d0f55SPeter Brune 
4923c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
4924c40d0f55SPeter Brune 
4925be95d8f1SBarry Smith .seealso: SNESSetNPCSide(), KSPGetPCSide()
4926c40d0f55SPeter Brune @*/
4927be95d8f1SBarry Smith PetscErrorCode  SNESGetNPCSide(SNES snes,PCSide *side)
4928c40d0f55SPeter Brune {
4929c40d0f55SPeter Brune   PetscFunctionBegin;
4930c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4931c40d0f55SPeter Brune   PetscValidPointer(side,2);
4932c40d0f55SPeter Brune   *side = snes->pcside;
4933c40d0f55SPeter Brune   PetscFunctionReturn(0);
4934c40d0f55SPeter Brune }
4935c40d0f55SPeter Brune 
49369e764e56SPeter Brune #undef __FUNCT__
49377601faf0SJed Brown #define __FUNCT__ "SNESSetLineSearch"
49389e764e56SPeter Brune /*@
49397601faf0SJed Brown   SNESSetLineSearch - Sets the linesearch on the SNES instance.
49409e764e56SPeter Brune 
49419e764e56SPeter Brune   Collective on SNES
49429e764e56SPeter Brune 
49439e764e56SPeter Brune   Input Parameters:
49449e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
49459e764e56SPeter Brune - linesearch   - the linesearch object
49469e764e56SPeter Brune 
49479e764e56SPeter Brune   Notes:
49487601faf0SJed Brown   Use SNESGetLineSearch() to retrieve the preconditioner context (for example,
49499e764e56SPeter Brune   to configure it using the API).
49509e764e56SPeter Brune 
49519e764e56SPeter Brune   Level: developer
49529e764e56SPeter Brune 
49539e764e56SPeter Brune .keywords: SNES, set, linesearch
49547601faf0SJed Brown .seealso: SNESGetLineSearch()
49559e764e56SPeter Brune @*/
49567601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch)
49579e764e56SPeter Brune {
49589e764e56SPeter Brune   PetscErrorCode ierr;
49599e764e56SPeter Brune 
49609e764e56SPeter Brune   PetscFunctionBegin;
49619e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4962f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
49639e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
49649e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4965f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
4966f5af7f23SKarl Rupp 
49679e764e56SPeter Brune   snes->linesearch = linesearch;
4968f5af7f23SKarl Rupp 
49693bb1ff40SBarry Smith   ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
49709e764e56SPeter Brune   PetscFunctionReturn(0);
49719e764e56SPeter Brune }
49729e764e56SPeter Brune 
49739e764e56SPeter Brune #undef __FUNCT__
49747601faf0SJed Brown #define __FUNCT__ "SNESGetLineSearch"
4975a34ceb2aSJed Brown /*@
49767601faf0SJed Brown   SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
49778141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
49789e764e56SPeter Brune 
49799e764e56SPeter Brune   Not Collective
49809e764e56SPeter Brune 
49819e764e56SPeter Brune   Input Parameter:
49829e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
49839e764e56SPeter Brune 
49849e764e56SPeter Brune   Output Parameter:
49859e764e56SPeter Brune . linesearch - linesearch context
49869e764e56SPeter Brune 
4987162e0bf5SPeter Brune   Level: beginner
49889e764e56SPeter Brune 
49899e764e56SPeter Brune .keywords: SNES, get, linesearch
4990162e0bf5SPeter Brune .seealso: SNESSetLineSearch(), SNESLineSearchCreate()
49919e764e56SPeter Brune @*/
49927601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch)
49939e764e56SPeter Brune {
49949e764e56SPeter Brune   PetscErrorCode ierr;
49959e764e56SPeter Brune   const char     *optionsprefix;
49969e764e56SPeter Brune 
49979e764e56SPeter Brune   PetscFunctionBegin;
49989e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
49999e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
50009e764e56SPeter Brune   if (!snes->linesearch) {
50019e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
500282f516ccSBarry Smith     ierr = SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch);CHKERRQ(ierr);
5003f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
5004b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
50059e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
50063bb1ff40SBarry Smith     ierr = PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch);CHKERRQ(ierr);
50079e764e56SPeter Brune   }
50089e764e56SPeter Brune   *linesearch = snes->linesearch;
50099e764e56SPeter Brune   PetscFunctionReturn(0);
50109e764e56SPeter Brune }
50119e764e56SPeter Brune 
501269b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
5013c6db04a5SJed Brown #include <mex.h>
501469b4f73cSBarry Smith 
50158f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
50168f6e6473SBarry Smith 
50170807856dSBarry Smith #undef __FUNCT__
50180807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
50190807856dSBarry Smith /*
5020bf388a1fSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with SNESSetFunctionMatlab().
50210807856dSBarry Smith 
50220807856dSBarry Smith    Collective on SNES
50230807856dSBarry Smith 
50240807856dSBarry Smith    Input Parameters:
50250807856dSBarry Smith +  snes - the SNES context
50260807856dSBarry Smith -  x - input vector
50270807856dSBarry Smith 
50280807856dSBarry Smith    Output Parameter:
50290807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
50300807856dSBarry Smith 
50310807856dSBarry Smith    Notes:
50320807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
50330807856dSBarry Smith    implementations, so most users would not generally call this routine
50340807856dSBarry Smith    themselves.
50350807856dSBarry Smith 
50360807856dSBarry Smith    Level: developer
50370807856dSBarry Smith 
50380807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
50390807856dSBarry Smith 
50400807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
504161b2408cSBarry Smith */
50427087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
50430807856dSBarry Smith {
5044e650e774SBarry Smith   PetscErrorCode    ierr;
50458f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
50468f6e6473SBarry Smith   int               nlhs  = 1,nrhs = 5;
50478f6e6473SBarry Smith   mxArray           *plhs[1],*prhs[5];
504891621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
5049e650e774SBarry Smith 
50500807856dSBarry Smith   PetscFunctionBegin;
50510807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
50520807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
50530807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
50540807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
50550807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
50560807856dSBarry Smith 
50570807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
5058e650e774SBarry Smith 
505991621f2eSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5060e650e774SBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5061e650e774SBarry Smith   ierr    = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
506291621f2eSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
506391621f2eSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
506491621f2eSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)ly);
50658f6e6473SBarry Smith   prhs[3] = mxCreateString(sctx->funcname);
50668f6e6473SBarry Smith   prhs[4] = sctx->ctx;
5067b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
5068e650e774SBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5069e650e774SBarry Smith   mxDestroyArray(prhs[0]);
5070e650e774SBarry Smith   mxDestroyArray(prhs[1]);
5071e650e774SBarry Smith   mxDestroyArray(prhs[2]);
50728f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
5073e650e774SBarry Smith   mxDestroyArray(plhs[0]);
50740807856dSBarry Smith   PetscFunctionReturn(0);
50750807856dSBarry Smith }
50760807856dSBarry Smith 
50770807856dSBarry Smith #undef __FUNCT__
50780807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
507961b2408cSBarry Smith /*
50800807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
50810807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5082e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
50830807856dSBarry Smith 
50840807856dSBarry Smith    Logically Collective on SNES
50850807856dSBarry Smith 
50860807856dSBarry Smith    Input Parameters:
50870807856dSBarry Smith +  snes - the SNES context
50880807856dSBarry Smith .  r - vector to store function value
5089f8b49ee9SBarry Smith -  f - function evaluation routine
50900807856dSBarry Smith 
50910807856dSBarry Smith    Notes:
50920807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
50930807856dSBarry Smith $      f'(x) x = -f(x),
50940807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
50950807856dSBarry Smith 
50960807856dSBarry Smith    Level: beginner
50970807856dSBarry Smith 
5098c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5099c5b75c40SBarry Smith 
51000807856dSBarry Smith .keywords: SNES, nonlinear, set, function
51010807856dSBarry Smith 
51020807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
510361b2408cSBarry Smith */
5104f8b49ee9SBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *f,mxArray *ctx)
51050807856dSBarry Smith {
51060807856dSBarry Smith   PetscErrorCode    ierr;
51078f6e6473SBarry Smith   SNESMatlabContext *sctx;
51080807856dSBarry Smith 
51090807856dSBarry Smith   PetscFunctionBegin;
51108f6e6473SBarry Smith   /* currently sctx is memory bleed */
5111854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5112f8b49ee9SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
51138f6e6473SBarry Smith   /*
51148f6e6473SBarry Smith      This should work, but it doesn't
51158f6e6473SBarry Smith   sctx->ctx = ctx;
51168f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
51178f6e6473SBarry Smith   */
51188f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
51198f6e6473SBarry Smith   ierr      = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
51200807856dSBarry Smith   PetscFunctionReturn(0);
51210807856dSBarry Smith }
512269b4f73cSBarry Smith 
512361b2408cSBarry Smith #undef __FUNCT__
512461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
512561b2408cSBarry Smith /*
5126bf388a1fSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with SNESSetJacobianMatlab().
512761b2408cSBarry Smith 
512861b2408cSBarry Smith    Collective on SNES
512961b2408cSBarry Smith 
513061b2408cSBarry Smith    Input Parameters:
513161b2408cSBarry Smith +  snes - the SNES context
513261b2408cSBarry Smith .  x - input vector
513361b2408cSBarry Smith .  A, B - the matrices
513461b2408cSBarry Smith -  ctx - user context
513561b2408cSBarry Smith 
513661b2408cSBarry Smith    Level: developer
513761b2408cSBarry Smith 
513861b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
513961b2408cSBarry Smith 
514061b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
514161b2408cSBarry Smith @*/
5142f3229a78SSatish Balay PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat A,Mat B,void *ctx)
514361b2408cSBarry Smith {
514461b2408cSBarry Smith   PetscErrorCode    ierr;
514561b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
514661b2408cSBarry Smith   int               nlhs  = 2,nrhs = 6;
514761b2408cSBarry Smith   mxArray           *plhs[2],*prhs[6];
514861b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
514961b2408cSBarry Smith 
515061b2408cSBarry Smith   PetscFunctionBegin;
515161b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
515261b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
515361b2408cSBarry Smith 
515461b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
515561b2408cSBarry Smith 
515661b2408cSBarry Smith   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
515761b2408cSBarry Smith   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
515861b2408cSBarry Smith   ierr    = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
515961b2408cSBarry Smith   ierr    = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
516061b2408cSBarry Smith   prhs[0] = mxCreateDoubleScalar((double)ls);
516161b2408cSBarry Smith   prhs[1] = mxCreateDoubleScalar((double)lx);
516261b2408cSBarry Smith   prhs[2] = mxCreateDoubleScalar((double)lA);
516361b2408cSBarry Smith   prhs[3] = mxCreateDoubleScalar((double)lB);
516461b2408cSBarry Smith   prhs[4] = mxCreateString(sctx->funcname);
516561b2408cSBarry Smith   prhs[5] = sctx->ctx;
5166b807a863SBarry Smith   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
516761b2408cSBarry Smith   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
516861b2408cSBarry Smith   mxDestroyArray(prhs[0]);
516961b2408cSBarry Smith   mxDestroyArray(prhs[1]);
517061b2408cSBarry Smith   mxDestroyArray(prhs[2]);
517161b2408cSBarry Smith   mxDestroyArray(prhs[3]);
517261b2408cSBarry Smith   mxDestroyArray(prhs[4]);
517361b2408cSBarry Smith   mxDestroyArray(plhs[0]);
517461b2408cSBarry Smith   mxDestroyArray(plhs[1]);
517561b2408cSBarry Smith   PetscFunctionReturn(0);
517661b2408cSBarry Smith }
517761b2408cSBarry Smith 
517861b2408cSBarry Smith #undef __FUNCT__
517961b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
518061b2408cSBarry Smith /*
518161b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
518261b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
5183e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
518461b2408cSBarry Smith 
518561b2408cSBarry Smith    Logically Collective on SNES
518661b2408cSBarry Smith 
518761b2408cSBarry Smith    Input Parameters:
518861b2408cSBarry Smith +  snes - the SNES context
518961b2408cSBarry Smith .  A,B - Jacobian matrices
5190f8b49ee9SBarry Smith .  J - function evaluation routine
519161b2408cSBarry Smith -  ctx - user context
519261b2408cSBarry Smith 
519361b2408cSBarry Smith    Level: developer
519461b2408cSBarry Smith 
5195c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5196c5b75c40SBarry Smith 
519761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
519861b2408cSBarry Smith 
5199f8b49ee9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction(), J
520061b2408cSBarry Smith */
5201f8b49ee9SBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *J,mxArray *ctx)
520261b2408cSBarry Smith {
520361b2408cSBarry Smith   PetscErrorCode    ierr;
520461b2408cSBarry Smith   SNESMatlabContext *sctx;
520561b2408cSBarry Smith 
520661b2408cSBarry Smith   PetscFunctionBegin;
520761b2408cSBarry Smith   /* currently sctx is memory bleed */
5208854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
5209f8b49ee9SBarry Smith   ierr = PetscStrallocpy(J,&sctx->funcname);CHKERRQ(ierr);
521061b2408cSBarry Smith   /*
521161b2408cSBarry Smith      This should work, but it doesn't
521261b2408cSBarry Smith   sctx->ctx = ctx;
521361b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
521461b2408cSBarry Smith   */
521561b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
521661b2408cSBarry Smith   ierr      = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
521761b2408cSBarry Smith   PetscFunctionReturn(0);
521861b2408cSBarry Smith }
521969b4f73cSBarry Smith 
5220f9eb7ae2SShri Abhyankar #undef __FUNCT__
5221f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
5222f9eb7ae2SShri Abhyankar /*
5223f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
5224f9eb7ae2SShri Abhyankar 
5225f9eb7ae2SShri Abhyankar    Collective on SNES
5226f9eb7ae2SShri Abhyankar 
5227f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
5228f9eb7ae2SShri Abhyankar @*/
52297087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
5230f9eb7ae2SShri Abhyankar {
5231f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
523248f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext*)ctx;
5233f9eb7ae2SShri Abhyankar   int               nlhs  = 1,nrhs = 6;
5234f9eb7ae2SShri Abhyankar   mxArray           *plhs[1],*prhs[6];
5235f9eb7ae2SShri Abhyankar   long long int     lx = 0,ls = 0;
5236f9eb7ae2SShri Abhyankar   Vec               x  = snes->vec_sol;
5237f9eb7ae2SShri Abhyankar 
5238f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5239f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
5240f9eb7ae2SShri Abhyankar 
5241f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
5242f9eb7ae2SShri Abhyankar   ierr    = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
5243f9eb7ae2SShri Abhyankar   prhs[0] = mxCreateDoubleScalar((double)ls);
5244f9eb7ae2SShri Abhyankar   prhs[1] = mxCreateDoubleScalar((double)it);
5245f9eb7ae2SShri Abhyankar   prhs[2] = mxCreateDoubleScalar((double)fnorm);
5246f9eb7ae2SShri Abhyankar   prhs[3] = mxCreateDoubleScalar((double)lx);
5247f9eb7ae2SShri Abhyankar   prhs[4] = mxCreateString(sctx->funcname);
5248f9eb7ae2SShri Abhyankar   prhs[5] = sctx->ctx;
5249f9eb7ae2SShri Abhyankar   ierr    = mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
5250f9eb7ae2SShri Abhyankar   ierr    = mxGetScalar(plhs[0]);CHKERRQ(ierr);
5251f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
5252f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
5253f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
5254f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
5255f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
5256f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
5257f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5258f9eb7ae2SShri Abhyankar }
5259f9eb7ae2SShri Abhyankar 
5260f9eb7ae2SShri Abhyankar #undef __FUNCT__
5261f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
5262f9eb7ae2SShri Abhyankar /*
5263e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5264f9eb7ae2SShri Abhyankar 
5265f9eb7ae2SShri Abhyankar    Level: developer
5266f9eb7ae2SShri Abhyankar 
5267c5b75c40SBarry Smith    Developer Note:  This bleeds the allocated memory SNESMatlabContext *sctx;
5268c5b75c40SBarry Smith 
5269f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
5270f9eb7ae2SShri Abhyankar 
5271f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5272f9eb7ae2SShri Abhyankar */
52736e4dcb14SBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *f,mxArray *ctx)
5274f9eb7ae2SShri Abhyankar {
5275f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
5276f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
5277f9eb7ae2SShri Abhyankar 
5278f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5279f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
5280854ce69bSBarry Smith   ierr = PetscNew(&sctx);CHKERRQ(ierr);
52816e4dcb14SBarry Smith   ierr = PetscStrallocpy(f,&sctx->funcname);CHKERRQ(ierr);
5282f9eb7ae2SShri Abhyankar   /*
5283f9eb7ae2SShri Abhyankar      This should work, but it doesn't
5284f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
5285f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
5286f9eb7ae2SShri Abhyankar   */
5287f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
52880298fd71SBarry Smith   ierr      = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,NULL);CHKERRQ(ierr);
5289f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5290f9eb7ae2SShri Abhyankar }
5291f9eb7ae2SShri Abhyankar 
529269b4f73cSBarry Smith #endif
5293