xref: /petsc/src/snes/interface/snes.c (revision 95eabced85bbc59f03a811c76dd44c473db4c8a2)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>                /*I "petscdmshell.h" I*/
4a64e098fSPeter Brune #include <petscsys.h>                    /*I "petscsys.h" I*/
59b94acceSBarry Smith 
6ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
78ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
88ba1e511SMatthew Knepley 
98ba1e511SMatthew Knepley /* Logging support */
1022c6f798SBarry Smith PetscClassId  SNES_CLASSID, DMSNES_CLASSID;
11f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
12a09944afSBarry Smith 
13a09944afSBarry Smith #undef __FUNCT__
14e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
15e113a28aSBarry Smith /*@
16e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
17e113a28aSBarry Smith 
183f9fe445SBarry Smith    Logically Collective on SNES
19e113a28aSBarry Smith 
20e113a28aSBarry Smith    Input Parameters:
21e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
22e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
23e113a28aSBarry Smith 
24e113a28aSBarry Smith    Options database keys:
25e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
26e113a28aSBarry Smith 
27e113a28aSBarry Smith    Level: intermediate
28e113a28aSBarry Smith 
29e113a28aSBarry Smith    Notes:
30e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
31e113a28aSBarry Smith     to determine if it has converged.
32e113a28aSBarry Smith 
33e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
34e113a28aSBarry Smith 
35e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
36e113a28aSBarry Smith @*/
377087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
38e113a28aSBarry Smith {
39e113a28aSBarry Smith   PetscFunctionBegin;
40e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
42e113a28aSBarry Smith   snes->errorifnotconverged = flg;
43dd568438SSatish Balay 
44e113a28aSBarry Smith   PetscFunctionReturn(0);
45e113a28aSBarry Smith }
46e113a28aSBarry Smith 
47e113a28aSBarry Smith #undef __FUNCT__
48e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
49e113a28aSBarry Smith /*@
50e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
51e113a28aSBarry Smith 
52e113a28aSBarry Smith    Not Collective
53e113a28aSBarry Smith 
54e113a28aSBarry Smith    Input Parameter:
55e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
56e113a28aSBarry Smith 
57e113a28aSBarry Smith    Output Parameter:
58e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
59e113a28aSBarry Smith 
60e113a28aSBarry Smith    Level: intermediate
61e113a28aSBarry Smith 
62e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
63e113a28aSBarry Smith 
64e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
65e113a28aSBarry Smith @*/
667087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
67e113a28aSBarry Smith {
68e113a28aSBarry Smith   PetscFunctionBegin;
69e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
70e113a28aSBarry Smith   PetscValidPointer(flag,2);
71e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
72e113a28aSBarry Smith   PetscFunctionReturn(0);
73e113a28aSBarry Smith }
74e113a28aSBarry Smith 
75e113a28aSBarry Smith #undef __FUNCT__
764936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
77e725d27bSBarry Smith /*@
784936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
794936397dSBarry Smith      in the functions domain. For example, negative pressure.
804936397dSBarry Smith 
813f9fe445SBarry Smith    Logically Collective on SNES
824936397dSBarry Smith 
834936397dSBarry Smith    Input Parameters:
846a388c36SPeter Brune .  snes - the SNES context
854936397dSBarry Smith 
8628529972SSatish Balay    Level: advanced
874936397dSBarry Smith 
884936397dSBarry Smith .keywords: SNES, view
894936397dSBarry Smith 
904936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
914936397dSBarry Smith @*/
927087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
934936397dSBarry Smith {
944936397dSBarry Smith   PetscFunctionBegin;
950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
964936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
974936397dSBarry Smith   PetscFunctionReturn(0);
984936397dSBarry Smith }
994936397dSBarry Smith 
1006a388c36SPeter Brune 
1016a388c36SPeter Brune #undef __FUNCT__
1026a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1036a388c36SPeter Brune /*@
104c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1056a388c36SPeter Brune 
1066a388c36SPeter Brune    Logically Collective on SNES
1076a388c36SPeter Brune 
1086a388c36SPeter Brune    Input Parameters:
1096a388c36SPeter Brune .  snes - the SNES context
1106a388c36SPeter Brune 
1116a388c36SPeter Brune    Output Parameters:
1126a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1136a388c36SPeter Brune 
1146a388c36SPeter Brune    Level: advanced
1156a388c36SPeter Brune 
1166a388c36SPeter Brune .keywords: SNES, view
1176a388c36SPeter Brune 
1186a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1196a388c36SPeter Brune @*/
1206a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1216a388c36SPeter Brune {
1226a388c36SPeter Brune   PetscFunctionBegin;
1236a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1246a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1256a388c36SPeter Brune   *domainerror = snes->domainerror;
1266a388c36SPeter Brune   PetscFunctionReturn(0);
1276a388c36SPeter Brune }
1286a388c36SPeter Brune 
12955849f57SBarry Smith #undef __FUNCT__
13055849f57SBarry Smith #define __FUNCT__ "SNESLoad"
13155849f57SBarry Smith /*@C
13255849f57SBarry Smith   SNESLoad - Loads a SNES that has been stored in binary  with SNESView().
13355849f57SBarry Smith 
13455849f57SBarry Smith   Collective on PetscViewer
13555849f57SBarry Smith 
13655849f57SBarry Smith   Input Parameters:
13755849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or
13855849f57SBarry Smith            some related function before a call to SNESLoad().
13955849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen()
14055849f57SBarry Smith 
14155849f57SBarry Smith    Level: intermediate
14255849f57SBarry Smith 
14355849f57SBarry Smith   Notes:
14455849f57SBarry Smith    The type is determined by the data in the file, any type set into the SNES before this call is ignored.
14555849f57SBarry Smith 
14655849f57SBarry Smith   Notes for advanced users:
14755849f57SBarry Smith   Most users should not need to know the details of the binary storage
14855849f57SBarry Smith   format, since SNESLoad() and TSView() completely hide these details.
14955849f57SBarry Smith   But for anyone who's interested, the standard binary matrix storage
15055849f57SBarry Smith   format is
15155849f57SBarry Smith .vb
15255849f57SBarry Smith      has not yet been determined
15355849f57SBarry Smith .ve
15455849f57SBarry Smith 
15555849f57SBarry Smith .seealso: PetscViewerBinaryOpen(), SNESView(), MatLoad(), VecLoad()
15655849f57SBarry Smith @*/
15755849f57SBarry Smith PetscErrorCode  SNESLoad(SNES newdm, PetscViewer viewer)
15855849f57SBarry Smith {
15955849f57SBarry Smith   PetscErrorCode ierr;
16055849f57SBarry Smith   PetscBool      isbinary;
16155849f57SBarry Smith   PetscInt       classid;
16255849f57SBarry Smith   char           type[256];
16355849f57SBarry Smith   KSP            ksp;
16455849f57SBarry Smith 
16555849f57SBarry Smith   PetscFunctionBegin;
16655849f57SBarry Smith   PetscValidHeaderSpecific(newdm,SNES_CLASSID,1);
16755849f57SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
16855849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
16955849f57SBarry Smith   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
17055849f57SBarry Smith 
17155849f57SBarry Smith   ierr = PetscViewerBinaryRead(viewer,&classid,1,PETSC_INT);CHKERRQ(ierr);
17255849f57SBarry Smith   if (classid != SNES_FILE_CLASSID) SETERRQ(((PetscObject)newdm)->comm,PETSC_ERR_ARG_WRONG,"Not SNES next in file");
17355849f57SBarry Smith   ierr = PetscViewerBinaryRead(viewer,type,256,PETSC_CHAR);CHKERRQ(ierr);
17455849f57SBarry Smith   ierr = SNESSetType(newdm, type);CHKERRQ(ierr);
175f2c2a1b9SBarry Smith   if (newdm->ops->load) {
17655849f57SBarry Smith     ierr = (*newdm->ops->load)(newdm,viewer);CHKERRQ(ierr);
177f2c2a1b9SBarry Smith   }
17855849f57SBarry Smith   ierr = SNESGetKSP(newdm,&ksp);CHKERRQ(ierr);
17955849f57SBarry Smith   ierr = KSPLoad(ksp,viewer);CHKERRQ(ierr);
18055849f57SBarry Smith   PetscFunctionReturn(0);
18155849f57SBarry Smith }
1826a388c36SPeter Brune 
1834936397dSBarry Smith #undef __FUNCT__
1844a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1857e2c5f70SBarry Smith /*@C
1869b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1879b94acceSBarry Smith 
1884c49b128SBarry Smith    Collective on SNES
189fee21e36SBarry Smith 
190c7afd0dbSLois Curfman McInnes    Input Parameters:
191c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
192c7afd0dbSLois Curfman McInnes -  viewer - visualization context
193c7afd0dbSLois Curfman McInnes 
1949b94acceSBarry Smith    Options Database Key:
195c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1969b94acceSBarry Smith 
1979b94acceSBarry Smith    Notes:
1989b94acceSBarry Smith    The available visualization contexts include
199b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
200b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
201c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
202c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
203c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
2049b94acceSBarry Smith 
2053e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
206b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
2079b94acceSBarry Smith 
20836851e7fSLois Curfman McInnes    Level: beginner
20936851e7fSLois Curfman McInnes 
2109b94acceSBarry Smith .keywords: SNES, view
2119b94acceSBarry Smith 
212b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
2139b94acceSBarry Smith @*/
2147087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
2159b94acceSBarry Smith {
216fa9f3622SBarry Smith   SNESKSPEW           *kctx;
217dfbe8321SBarry Smith   PetscErrorCode      ierr;
21894b7f48cSBarry Smith   KSP                 ksp;
2197f1410a3SPeter Brune   SNESLineSearch      linesearch;
22072a02f06SBarry Smith   PetscBool           iascii,isstring,isbinary,isdraw;
2219b94acceSBarry Smith 
2223a40ed3dSBarry Smith   PetscFunctionBegin;
2230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2243050cee2SBarry Smith   if (!viewer) {
2257adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
2263050cee2SBarry Smith   }
2270700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
228c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
22974679c65SBarry Smith 
230251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
231251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
23255849f57SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
23372a02f06SBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr);
23432077d6dSBarry Smith   if (iascii) {
235317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
236e7788613SBarry Smith     if (snes->ops->view) {
237b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
238e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
239b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2400ef38995SBarry Smith     }
24177431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
242a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
243c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
24477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
24577431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
24617fe4bdfSPeter Brune     if (snes->gridsequence) {
24717fe4bdfSPeter Brune       ierr = PetscViewerASCIIPrintf(viewer,"  total number of grid sequence refinements=%D\n",snes->gridsequence);CHKERRQ(ierr);
24817fe4bdfSPeter Brune     }
2499b94acceSBarry Smith     if (snes->ksp_ewconv) {
250fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2519b94acceSBarry Smith       if (kctx) {
25277431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
253a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
254a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2559b94acceSBarry Smith       }
2569b94acceSBarry Smith     }
257eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
258eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
259eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
260eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
261eb1f6c34SBarry Smith     }
262eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
263eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
264eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
26542f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
266eb1f6c34SBarry Smith     }
2670f5bd95cSBarry Smith   } else if (isstring) {
268317d6ea6SBarry Smith     const char *type;
269454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
270b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
27155849f57SBarry Smith   } else if (isbinary) {
27255849f57SBarry Smith     PetscInt         classid = SNES_FILE_CLASSID;
27355849f57SBarry Smith     MPI_Comm         comm;
27455849f57SBarry Smith     PetscMPIInt      rank;
27555849f57SBarry Smith     char             type[256];
27655849f57SBarry Smith 
27755849f57SBarry Smith     ierr = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
27855849f57SBarry Smith     ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
27955849f57SBarry Smith     if (!rank) {
28055849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
28155849f57SBarry Smith       ierr = PetscStrncpy(type,((PetscObject)snes)->type_name,256);CHKERRQ(ierr);
28255849f57SBarry Smith       ierr = PetscViewerBinaryWrite(viewer,type,256,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
28355849f57SBarry Smith     }
28455849f57SBarry Smith     if (snes->ops->view) {
28555849f57SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
28655849f57SBarry Smith     }
28772a02f06SBarry Smith   } else if (isdraw) {
28872a02f06SBarry Smith     PetscDraw draw;
28972a02f06SBarry Smith     char      str[36];
29089fd9fafSBarry Smith     PetscReal x,y,bottom,h;
29172a02f06SBarry Smith 
29272a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
29372a02f06SBarry Smith     ierr = PetscDrawGetCurrentPoint(draw,&x,&y);CHKERRQ(ierr);
29472a02f06SBarry Smith     ierr = PetscStrcpy(str,"SNES: ");CHKERRQ(ierr);
29572a02f06SBarry Smith     ierr = PetscStrcat(str,((PetscObject)snes)->type_name);CHKERRQ(ierr);
29689fd9fafSBarry Smith     ierr = PetscDrawBoxedString(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,PETSC_NULL,&h);CHKERRQ(ierr);
29789fd9fafSBarry Smith     bottom = y - h;
29872a02f06SBarry Smith     ierr = PetscDrawPushCurrentPoint(draw,x,bottom);CHKERRQ(ierr);
29972a02f06SBarry Smith   }
30072a02f06SBarry Smith   if (snes->linesearch) {
30172a02f06SBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
30272a02f06SBarry Smith     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
30372a02f06SBarry Smith     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
30472a02f06SBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
30519bcc07fSBarry Smith   }
30642f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
3074a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
3084a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
3094a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3104a0c5b0cSMatthew G Knepley   }
3112c155ee1SBarry Smith   if (snes->usesksp) {
3122c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
313b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
31494b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
315b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
3162c155ee1SBarry Smith   }
31772a02f06SBarry Smith   if (isdraw) {
31872a02f06SBarry Smith     PetscDraw draw;
31972a02f06SBarry Smith     ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr);
32072a02f06SBarry Smith     ierr = PetscDrawPopCurrentPoint(draw);CHKERRQ(ierr);
3217f1410a3SPeter Brune   }
3223a40ed3dSBarry Smith   PetscFunctionReturn(0);
3239b94acceSBarry Smith }
3249b94acceSBarry Smith 
32576b2cf59SMatthew Knepley /*
32676b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
32776b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
32876b2cf59SMatthew Knepley */
32976b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
330a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
3316849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
33276b2cf59SMatthew Knepley 
333e74ef692SMatthew Knepley #undef __FUNCT__
334e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
335ac226902SBarry Smith /*@C
33676b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
33776b2cf59SMatthew Knepley 
33876b2cf59SMatthew Knepley   Not Collective
33976b2cf59SMatthew Knepley 
34076b2cf59SMatthew Knepley   Input Parameter:
34176b2cf59SMatthew Knepley . snescheck - function that checks for options
34276b2cf59SMatthew Knepley 
34376b2cf59SMatthew Knepley   Level: developer
34476b2cf59SMatthew Knepley 
34576b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
34676b2cf59SMatthew Knepley @*/
3477087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
34876b2cf59SMatthew Knepley {
34976b2cf59SMatthew Knepley   PetscFunctionBegin;
35076b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
351e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
35276b2cf59SMatthew Knepley   }
35376b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
35476b2cf59SMatthew Knepley   PetscFunctionReturn(0);
35576b2cf59SMatthew Knepley }
35676b2cf59SMatthew Knepley 
3577087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
358aa3661deSLisandro Dalcin 
359aa3661deSLisandro Dalcin #undef __FUNCT__
360aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
361ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
362aa3661deSLisandro Dalcin {
363aa3661deSLisandro Dalcin   Mat            J;
364aa3661deSLisandro Dalcin   KSP            ksp;
365aa3661deSLisandro Dalcin   PC             pc;
366ace3abfcSBarry Smith   PetscBool      match;
367aa3661deSLisandro Dalcin   PetscErrorCode ierr;
368aa3661deSLisandro Dalcin 
369aa3661deSLisandro Dalcin   PetscFunctionBegin;
3700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
371aa3661deSLisandro Dalcin 
37298613b67SLisandro Dalcin   if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
37398613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
37498613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
37598613b67SLisandro Dalcin   }
37698613b67SLisandro Dalcin 
377aa3661deSLisandro Dalcin   if (version == 1) {
378aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
37998613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3809c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
381aa3661deSLisandro Dalcin   } else if (version == 2) {
382e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
38382a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
384aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
385aa3661deSLisandro Dalcin #else
386e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
387aa3661deSLisandro Dalcin #endif
388a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
389aa3661deSLisandro Dalcin 
390aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
391d3462f78SMatthew Knepley   if (hasOperator) {
3923232da50SPeter Brune 
393aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
394aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
395aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
396aa3661deSLisandro Dalcin   } else {
397aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
3983232da50SPeter Brune      provided preconditioner Jacobian with the default matrix free version. */
3993232da50SPeter Brune 
40028a52e04SBarry Smith     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,0);CHKERRQ(ierr);
401aa3661deSLisandro Dalcin     /* Force no preconditioner */
402aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
403aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
404251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
405aa3661deSLisandro Dalcin     if (!match) {
406aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
407aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
408aa3661deSLisandro Dalcin     }
409aa3661deSLisandro Dalcin   }
4106bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
411aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
412aa3661deSLisandro Dalcin }
413aa3661deSLisandro Dalcin 
4144a2ae208SSatish Balay #undef __FUNCT__
415dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
416dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
417dfe15315SJed Brown {
418dfe15315SJed Brown   SNES snes = (SNES)ctx;
419dfe15315SJed Brown   PetscErrorCode ierr;
420dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
421dfe15315SJed Brown 
422dfe15315SJed Brown   PetscFunctionBegin;
42316ebb321SJed Brown   if (PetscLogPrintInfo) {
42416ebb321SJed Brown     PetscInt finelevel,coarselevel,fineclevel,coarseclevel;
42516ebb321SJed Brown     ierr = DMGetRefineLevel(dmfine,&finelevel);CHKERRQ(ierr);
42616ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmfine,&fineclevel);CHKERRQ(ierr);
42716ebb321SJed Brown     ierr = DMGetRefineLevel(dmcoarse,&coarselevel);CHKERRQ(ierr);
42816ebb321SJed Brown     ierr = DMGetCoarsenLevel(dmcoarse,&coarseclevel);CHKERRQ(ierr);
42916ebb321SJed Brown     ierr = PetscInfo4(dmfine,"Restricting SNES solution vector from level %D-%D to level %D-%D\n",finelevel,fineclevel,coarselevel,coarseclevel);CHKERRQ(ierr);
43016ebb321SJed Brown   }
431dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
432dfe15315SJed Brown   else {
433dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
434dfe15315SJed Brown     Xfine = Xfine_named;
435dfe15315SJed Brown   }
436dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
437dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
438dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
439dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
440dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
441dfe15315SJed Brown   PetscFunctionReturn(0);
442dfe15315SJed Brown }
443dfe15315SJed Brown 
444dfe15315SJed Brown #undef __FUNCT__
44516ebb321SJed Brown #define __FUNCT__ "DMCoarsenHook_SNESVecSol"
44616ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx)
44716ebb321SJed Brown {
44816ebb321SJed Brown   PetscErrorCode ierr;
44916ebb321SJed Brown 
45016ebb321SJed Brown   PetscFunctionBegin;
45116ebb321SJed Brown   ierr = DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx);CHKERRQ(ierr);
45216ebb321SJed Brown   PetscFunctionReturn(0);
45316ebb321SJed Brown }
45416ebb321SJed Brown 
45516ebb321SJed Brown #undef __FUNCT__
456caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
457a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
458a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
459caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
460caa4e7f2SJed Brown {
461caa4e7f2SJed Brown   SNES                        snes = (SNES)ctx;
462caa4e7f2SJed Brown   PetscErrorCode              ierr;
463caa4e7f2SJed Brown   Mat                         Asave = A,Bsave = B;
464dfe15315SJed Brown   Vec                         X,Xnamed = PETSC_NULL;
465dfe15315SJed Brown   DM                          dmsave;
4664e269d77SPeter Brune   void                        *ctxsave;
4674e269d77SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
468caa4e7f2SJed Brown 
469caa4e7f2SJed Brown   PetscFunctionBegin;
470dfe15315SJed Brown   dmsave = snes->dm;
471dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
472dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
473dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
474dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
475dfe15315SJed Brown     X = Xnamed;
4764e269d77SPeter Brune     ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,&jac,&ctxsave);CHKERRQ(ierr);
4774e269d77SPeter Brune     /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */
4784e269d77SPeter Brune     if (jac == SNESDefaultComputeJacobianColor) {
4794e269d77SPeter Brune       ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr);
480dfe15315SJed Brown     }
4814e269d77SPeter Brune   }
4824e269d77SPeter Brune   /* put the previous context back */
4834e269d77SPeter Brune 
484dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
4854e269d77SPeter Brune   if (snes->dm != dmsave && jac == SNESDefaultComputeJacobianColor) {
4864e269d77SPeter Brune     ierr = SNESSetJacobian(snes,PETSC_NULL,PETSC_NULL,jac,ctxsave);CHKERRQ(ierr);
4874e269d77SPeter Brune   }
4884e269d77SPeter Brune 
489caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
490dfe15315SJed Brown   if (Xnamed) {
491dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
492dfe15315SJed Brown   }
493dfe15315SJed Brown   snes->dm = dmsave;
494caa4e7f2SJed Brown   PetscFunctionReturn(0);
495caa4e7f2SJed Brown }
496caa4e7f2SJed Brown 
497caa4e7f2SJed Brown #undef __FUNCT__
4986cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
4996cab3a1bSJed Brown /*@
5006cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
5016cab3a1bSJed Brown 
5026cab3a1bSJed Brown    Collective
5036cab3a1bSJed Brown 
5046cab3a1bSJed Brown    Input Arguments:
5056cab3a1bSJed Brown .  snes - snes to configure
5066cab3a1bSJed Brown 
5076cab3a1bSJed Brown    Level: developer
5086cab3a1bSJed Brown 
5096cab3a1bSJed Brown .seealso: SNESSetUp()
5106cab3a1bSJed Brown @*/
5116cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
5126cab3a1bSJed Brown {
5136cab3a1bSJed Brown   PetscErrorCode ierr;
5146cab3a1bSJed Brown   DM             dm;
515942e3340SBarry Smith   DMSNES         sdm;
5166cab3a1bSJed Brown 
5176cab3a1bSJed Brown   PetscFunctionBegin;
5186cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
519942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
52022c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
521942e3340SBarry Smith     SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_PLIB,"DMSNES not properly configured");
5223232da50SPeter Brune   } else if (!snes->jacobian && snes->mf) {
5236cab3a1bSJed Brown     Mat J;
5246cab3a1bSJed Brown     void *functx;
5256cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
5266cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5276cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
5286cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
5293232da50SPeter Brune     ierr = SNESSetJacobian(snes,J,J,0,0);CHKERRQ(ierr);
5306cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
531caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
5326cab3a1bSJed Brown     Mat J,B;
5336cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
5346cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
5356cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
5366cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
53706f20277SJed Brown     /* sdm->computejacobian was already set to reach here */
53806f20277SJed Brown     ierr = SNESSetJacobian(snes,J,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
5396cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
5406cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
541caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
5426cab3a1bSJed Brown     Mat J,B;
5436cab3a1bSJed Brown     J = snes->jacobian;
5446cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
5456cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
5466cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
5476cab3a1bSJed Brown   }
548caa4e7f2SJed Brown   {
549caa4e7f2SJed Brown     KSP ksp;
550caa4e7f2SJed Brown     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
551caa4e7f2SJed Brown     ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
55216ebb321SJed Brown     ierr = DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
553caa4e7f2SJed Brown   }
5546cab3a1bSJed Brown   PetscFunctionReturn(0);
5556cab3a1bSJed Brown }
5566cab3a1bSJed Brown 
5576cab3a1bSJed Brown #undef __FUNCT__
5584a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
5599b94acceSBarry Smith /*@
56094b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
5619b94acceSBarry Smith 
562c7afd0dbSLois Curfman McInnes    Collective on SNES
563c7afd0dbSLois Curfman McInnes 
5649b94acceSBarry Smith    Input Parameter:
5659b94acceSBarry Smith .  snes - the SNES context
5669b94acceSBarry Smith 
56736851e7fSLois Curfman McInnes    Options Database Keys:
568ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
56982738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
57082738288SBarry Smith                 of the change in the solution between steps
57170441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
572b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
573b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
574b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
5754839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
576ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
577a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
578e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
579b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
5802492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
58182738288SBarry Smith                                solver; hence iterations will continue until max_it
5821fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
58382738288SBarry Smith                                of convergence test
584e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
585e8105e01SRichard Katz                                        filename given prints to stdout
586a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
587a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
588a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
5894619e776SBarry Smith .  -snes_monitor_lg_residualnorm - plots residual norm at each iteration
590459f5d12SBarry Smith .  -snes_monitor_lg_range - plots residual norm at each iteration
591e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
592e2e60de9SPeter Brune .  -snes_fd_color - use finite differences with coloring to compute Jacobian
5935968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
594fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
59582738288SBarry Smith 
59682738288SBarry Smith     Options Database for Eisenstat-Walker method:
597fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
5984b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
59936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
60036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
60136851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
60236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
60336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
60436851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
60582738288SBarry Smith 
60611ca99fdSLois Curfman McInnes    Notes:
60711ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
6080598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
60983e2fdc7SBarry Smith 
61036851e7fSLois Curfman McInnes    Level: beginner
61136851e7fSLois Curfman McInnes 
6129b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
6139b94acceSBarry Smith 
61469ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
6159b94acceSBarry Smith @*/
6167087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
6179b94acceSBarry Smith {
618d8f46077SPeter Brune   PetscBool               flg,pcset;
619d8f46077SPeter Brune   PetscInt                i,indx,lag,grids;
620aa3661deSLisandro Dalcin   MatStructure            matflag;
62185385478SLisandro Dalcin   const char              *deft = SNESLS;
62285385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
62385385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
624e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
625649052a6SBarry Smith   PetscViewer             monviewer;
62685385478SLisandro Dalcin   PetscErrorCode          ierr;
627c40d0f55SPeter Brune   PCSide                  pcside;
628a64e098fSPeter Brune   const char              *optionsprefix;
6299b94acceSBarry Smith 
6303a40ed3dSBarry Smith   PetscFunctionBegin;
6310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
632ca161407SBarry Smith 
633186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
6343194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
6357adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
636b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
637d64ed03dSBarry Smith     if (flg) {
638186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
6397adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
640186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
641d64ed03dSBarry Smith     }
64290d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
643909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
64493c39befSBarry Smith 
645c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
64657034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
647186905e3SBarry Smith 
64857034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
649b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
650b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
65124254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
652ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
653acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
65485385478SLisandro Dalcin 
655a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
656a8054027SBarry Smith     if (flg) {
657a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
658a8054027SBarry Smith     }
659e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
660e35cf81dSBarry Smith     if (flg) {
661e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
662e35cf81dSBarry Smith     }
663efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
664efd51863SBarry Smith     if (flg) {
665efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
666efd51863SBarry Smith     }
667a8054027SBarry Smith 
66885385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
66985385478SLisandro Dalcin     if (flg) {
67085385478SLisandro Dalcin       switch (indx) {
6717f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
6727f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
67385385478SLisandro Dalcin       }
67485385478SLisandro Dalcin     }
67585385478SLisandro Dalcin 
676acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
677186905e3SBarry Smith 
678fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
679fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
680fdacfa88SPeter Brune 
68185385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
68285385478SLisandro Dalcin 
683acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
684186905e3SBarry Smith 
685fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
686fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
687fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
688fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
689fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
690fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
691fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
692186905e3SBarry Smith 
69390d69ab7SBarry Smith     flg  = PETSC_FALSE;
694acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
695a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
696eabae89aSBarry Smith 
697a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
698e8105e01SRichard Katz     if (flg) {
699649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
700649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
701e8105e01SRichard Katz     }
702eabae89aSBarry Smith 
703b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
704b271bb04SBarry Smith     if (flg) {
705b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
706b271bb04SBarry Smith     }
707b271bb04SBarry Smith 
708a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
709eabae89aSBarry Smith     if (flg) {
710649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
711f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
712e8105e01SRichard Katz     }
713eabae89aSBarry Smith 
714a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
715eabae89aSBarry Smith     if (flg) {
716649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
717649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
718eabae89aSBarry Smith     }
719eabae89aSBarry Smith 
7205180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
7215180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
7225180491cSLisandro Dalcin 
72390d69ab7SBarry Smith     flg  = PETSC_FALSE;
724acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
725a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
72690d69ab7SBarry Smith     flg  = PETSC_FALSE;
727acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
728a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
72990d69ab7SBarry Smith     flg  = PETSC_FALSE;
730acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
731a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
73290d69ab7SBarry Smith     flg  = PETSC_FALSE;
7334619e776SBarry Smith     ierr = PetscOptionsBool("-snes_monitor_lg_residualnorm","Plot function norm at each iteration","SNESMonitorLGResidualNorm",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
734459f5d12SBarry Smith     if (flg) {
735459f5d12SBarry Smith       PetscDrawLG ctx;
736459f5d12SBarry Smith 
737459f5d12SBarry Smith       ierr = SNESMonitorLGCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr);
738459f5d12SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))SNESMonitorLGDestroy);CHKERRQ(ierr);
739459f5d12SBarry Smith     }
74090d69ab7SBarry Smith     flg  = PETSC_FALSE;
7414619e776SBarry Smith     ierr = PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
742459f5d12SBarry Smith     if (flg) {
743459f5d12SBarry Smith       PetscViewer ctx;
744e24b481bSBarry Smith 
745459f5d12SBarry Smith       ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);CHKERRQ(ierr);
746459f5d12SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
747459f5d12SBarry Smith     }
7482e7541e6SPeter Brune 
7492e7541e6SPeter Brune     flg  = PETSC_FALSE;
7502e7541e6SPeter Brune     ierr = PetscOptionsBool("-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
7512e7541e6SPeter Brune     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorJacUpdateSpectrum,0,0);CHKERRQ(ierr);}
7522e7541e6SPeter Brune 
75390d69ab7SBarry Smith     flg  = PETSC_FALSE;
754acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
7554b27c08aSLois Curfman McInnes     if (flg) {
7566cab3a1bSJed Brown       void *functx;
7576cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
7586cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
759ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
7609b94acceSBarry Smith     }
761639f9d9dSBarry Smith 
76244848bc4SPeter Brune     flg  = PETSC_FALSE;
76397584545SPeter Brune     ierr = PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESDefaultObjectiveComputeFunctionFD",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
76497584545SPeter Brune     if (flg) {
76597584545SPeter Brune       ierr = SNESSetFunction(snes,PETSC_NULL,SNESDefaultObjectiveComputeFunctionFD,PETSC_NULL);CHKERRQ(ierr);
76697584545SPeter Brune     }
76797584545SPeter Brune 
76897584545SPeter Brune     flg  = PETSC_FALSE;
76944848bc4SPeter Brune     ierr = PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESDefaultComputeJacobianColor",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
77044848bc4SPeter Brune     if (flg) {
77144848bc4SPeter Brune       void *functx;
77244848bc4SPeter Brune       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
7730171d955SPeter Brune       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobianColor,0);CHKERRQ(ierr);
77444848bc4SPeter Brune       ierr = PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n");CHKERRQ(ierr);
77544848bc4SPeter Brune     }
77644848bc4SPeter Brune 
777aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
778d8f46077SPeter 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);
779d8f46077SPeter Brune     if (flg && snes->mf_operator) {
780a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
781d8f46077SPeter Brune       snes->mf = PETSC_TRUE;
782a8248277SBarry Smith     }
783aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
784d8f46077SPeter Brune     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&snes->mf,&flg);CHKERRQ(ierr);
785d8f46077SPeter Brune     if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE;
786d8f46077SPeter Brune     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,0);CHKERRQ(ierr);
787d28543b3SPeter Brune 
788c40d0f55SPeter Brune     flg = PETSC_FALSE;
789c40d0f55SPeter Brune     ierr = SNESGetPCSide(snes,&pcside);
790c40d0f55SPeter Brune     ierr = PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);CHKERRQ(ierr);
791c40d0f55SPeter Brune     if (flg) {ierr = SNESSetPCSide(snes,pcside);CHKERRQ(ierr);}
792c40d0f55SPeter Brune 
79389b92e6fSPeter Brune     /* GS Options */
79489b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
79589b92e6fSPeter Brune 
79676b2cf59SMatthew Knepley     for (i = 0; i < numberofsetfromoptions; i++) {
79776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
79876b2cf59SMatthew Knepley     }
79976b2cf59SMatthew Knepley 
800e7788613SBarry Smith     if (snes->ops->setfromoptions) {
801e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
802639f9d9dSBarry Smith     }
8035d973c19SBarry Smith 
8045d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
8055d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
806b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
8074bbc92c1SBarry Smith 
8081cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
809aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
810aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
81185385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
81293993e2dSLois Curfman McInnes 
8139e764e56SPeter Brune   if (!snes->linesearch) {
814f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
8159e764e56SPeter Brune   }
816f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
8179e764e56SPeter Brune 
81851e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
81951e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
82051e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
82151e86f29SPeter Brune   if (pcset && (!snes->pc)) {
82251e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
82351e86f29SPeter Brune   }
8243a40ed3dSBarry Smith   PetscFunctionReturn(0);
8259b94acceSBarry Smith }
8269b94acceSBarry Smith 
827d25893d9SBarry Smith #undef __FUNCT__
828d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
829d25893d9SBarry Smith /*@
830d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
831d25893d9SBarry Smith    the nonlinear solvers.
832d25893d9SBarry Smith 
833d25893d9SBarry Smith    Logically Collective on SNES
834d25893d9SBarry Smith 
835d25893d9SBarry Smith    Input Parameters:
836d25893d9SBarry Smith +  snes - the SNES context
837d25893d9SBarry Smith .  compute - function to compute the context
838d25893d9SBarry Smith -  destroy - function to destroy the context
839d25893d9SBarry Smith 
840d25893d9SBarry Smith    Level: intermediate
841d25893d9SBarry Smith 
842d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
843d25893d9SBarry Smith 
844d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
845d25893d9SBarry Smith @*/
846d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
847d25893d9SBarry Smith {
848d25893d9SBarry Smith   PetscFunctionBegin;
849d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
850d25893d9SBarry Smith   snes->ops->usercompute = compute;
851d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
852d25893d9SBarry Smith   PetscFunctionReturn(0);
853d25893d9SBarry Smith }
854a847f771SSatish Balay 
8554a2ae208SSatish Balay #undef __FUNCT__
8564a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
857b07ff414SBarry Smith /*@
8589b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
8599b94acceSBarry Smith    the nonlinear solvers.
8609b94acceSBarry Smith 
8613f9fe445SBarry Smith    Logically Collective on SNES
862fee21e36SBarry Smith 
863c7afd0dbSLois Curfman McInnes    Input Parameters:
864c7afd0dbSLois Curfman McInnes +  snes - the SNES context
865c7afd0dbSLois Curfman McInnes -  usrP - optional user context
866c7afd0dbSLois Curfman McInnes 
86736851e7fSLois Curfman McInnes    Level: intermediate
86836851e7fSLois Curfman McInnes 
8699b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
8709b94acceSBarry Smith 
871ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
8729b94acceSBarry Smith @*/
8737087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
8749b94acceSBarry Smith {
8751b2093e4SBarry Smith   PetscErrorCode ierr;
876b07ff414SBarry Smith   KSP            ksp;
8771b2093e4SBarry Smith 
8783a40ed3dSBarry Smith   PetscFunctionBegin;
8790700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
880b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
881b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
8829b94acceSBarry Smith   snes->user = usrP;
8833a40ed3dSBarry Smith   PetscFunctionReturn(0);
8849b94acceSBarry Smith }
88574679c65SBarry Smith 
8864a2ae208SSatish Balay #undef __FUNCT__
8874a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
888b07ff414SBarry Smith /*@
8899b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
8909b94acceSBarry Smith    nonlinear solvers.
8919b94acceSBarry Smith 
892c7afd0dbSLois Curfman McInnes    Not Collective
893c7afd0dbSLois Curfman McInnes 
8949b94acceSBarry Smith    Input Parameter:
8959b94acceSBarry Smith .  snes - SNES context
8969b94acceSBarry Smith 
8979b94acceSBarry Smith    Output Parameter:
8989b94acceSBarry Smith .  usrP - user context
8999b94acceSBarry Smith 
90036851e7fSLois Curfman McInnes    Level: intermediate
90136851e7fSLois Curfman McInnes 
9029b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
9039b94acceSBarry Smith 
9049b94acceSBarry Smith .seealso: SNESSetApplicationContext()
9059b94acceSBarry Smith @*/
906e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
9079b94acceSBarry Smith {
9083a40ed3dSBarry Smith   PetscFunctionBegin;
9090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
910e71120c6SJed Brown   *(void**)usrP = snes->user;
9113a40ed3dSBarry Smith   PetscFunctionReturn(0);
9129b94acceSBarry Smith }
91374679c65SBarry Smith 
9144a2ae208SSatish Balay #undef __FUNCT__
9154a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
9169b94acceSBarry Smith /*@
917c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
918c8228a4eSBarry Smith    at this time.
9199b94acceSBarry Smith 
920c7afd0dbSLois Curfman McInnes    Not Collective
921c7afd0dbSLois Curfman McInnes 
9229b94acceSBarry Smith    Input Parameter:
9239b94acceSBarry Smith .  snes - SNES context
9249b94acceSBarry Smith 
9259b94acceSBarry Smith    Output Parameter:
9269b94acceSBarry Smith .  iter - iteration number
9279b94acceSBarry Smith 
928c8228a4eSBarry Smith    Notes:
929c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
930c8228a4eSBarry Smith 
931c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
93208405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
93308405cd6SLois Curfman McInnes .vb
93408405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
93508405cd6SLois Curfman McInnes       if (!(it % 2)) {
93608405cd6SLois Curfman McInnes         [compute Jacobian here]
93708405cd6SLois Curfman McInnes       }
93808405cd6SLois Curfman McInnes .ve
939c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
94008405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
941c8228a4eSBarry Smith 
94236851e7fSLois Curfman McInnes    Level: intermediate
94336851e7fSLois Curfman McInnes 
9442b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
9452b668275SBarry Smith 
946b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
9479b94acceSBarry Smith @*/
9487087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
9499b94acceSBarry Smith {
9503a40ed3dSBarry Smith   PetscFunctionBegin;
9510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9524482741eSBarry Smith   PetscValidIntPointer(iter,2);
9539b94acceSBarry Smith   *iter = snes->iter;
9543a40ed3dSBarry Smith   PetscFunctionReturn(0);
9559b94acceSBarry Smith }
95674679c65SBarry Smith 
9574a2ae208SSatish Balay #undef __FUNCT__
958360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
959360c497dSPeter Brune /*@
960360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
961360c497dSPeter Brune 
962360c497dSPeter Brune    Not Collective
963360c497dSPeter Brune 
964360c497dSPeter Brune    Input Parameter:
965360c497dSPeter Brune .  snes - SNES context
966360c497dSPeter Brune .  iter - iteration number
967360c497dSPeter Brune 
968360c497dSPeter Brune    Level: developer
969360c497dSPeter Brune 
970360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
971360c497dSPeter Brune 
972360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
973360c497dSPeter Brune @*/
974360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
975360c497dSPeter Brune {
976360c497dSPeter Brune   PetscErrorCode ierr;
977360c497dSPeter Brune 
978360c497dSPeter Brune   PetscFunctionBegin;
979360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
980360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
981360c497dSPeter Brune   snes->iter = iter;
982360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
983360c497dSPeter Brune   PetscFunctionReturn(0);
984360c497dSPeter Brune }
985360c497dSPeter Brune 
986360c497dSPeter Brune #undef __FUNCT__
9874a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
9889b94acceSBarry Smith /*@
9899b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
9909b94acceSBarry Smith    with SNESSSetFunction().
9919b94acceSBarry Smith 
992c7afd0dbSLois Curfman McInnes    Collective on SNES
993c7afd0dbSLois Curfman McInnes 
9949b94acceSBarry Smith    Input Parameter:
9959b94acceSBarry Smith .  snes - SNES context
9969b94acceSBarry Smith 
9979b94acceSBarry Smith    Output Parameter:
9989b94acceSBarry Smith .  fnorm - 2-norm of function
9999b94acceSBarry Smith 
100036851e7fSLois Curfman McInnes    Level: intermediate
100136851e7fSLois Curfman McInnes 
10029b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
1003a86d99e1SLois Curfman McInnes 
1004b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
10059b94acceSBarry Smith @*/
10067087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
10079b94acceSBarry Smith {
10083a40ed3dSBarry Smith   PetscFunctionBegin;
10090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10104482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
10119b94acceSBarry Smith   *fnorm = snes->norm;
10123a40ed3dSBarry Smith   PetscFunctionReturn(0);
10139b94acceSBarry Smith }
101474679c65SBarry Smith 
1015360c497dSPeter Brune 
1016360c497dSPeter Brune #undef __FUNCT__
1017360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
1018360c497dSPeter Brune /*@
1019360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
1020360c497dSPeter Brune 
1021360c497dSPeter Brune    Collective on SNES
1022360c497dSPeter Brune 
1023360c497dSPeter Brune    Input Parameter:
1024360c497dSPeter Brune .  snes - SNES context
1025360c497dSPeter Brune .  fnorm - 2-norm of function
1026360c497dSPeter Brune 
1027360c497dSPeter Brune    Level: developer
1028360c497dSPeter Brune 
1029360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
1030360c497dSPeter Brune 
1031360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
1032360c497dSPeter Brune @*/
1033360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
1034360c497dSPeter Brune {
1035360c497dSPeter Brune 
1036360c497dSPeter Brune   PetscErrorCode ierr;
1037360c497dSPeter Brune 
1038360c497dSPeter Brune   PetscFunctionBegin;
1039360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1040360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
1041360c497dSPeter Brune   snes->norm = fnorm;
1042360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
1043360c497dSPeter Brune   PetscFunctionReturn(0);
1044360c497dSPeter Brune }
1045360c497dSPeter Brune 
10464a2ae208SSatish Balay #undef __FUNCT__
1047b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
10489b94acceSBarry Smith /*@
1049b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
10509b94acceSBarry Smith    attempted by the nonlinear solver.
10519b94acceSBarry Smith 
1052c7afd0dbSLois Curfman McInnes    Not Collective
1053c7afd0dbSLois Curfman McInnes 
10549b94acceSBarry Smith    Input Parameter:
10559b94acceSBarry Smith .  snes - SNES context
10569b94acceSBarry Smith 
10579b94acceSBarry Smith    Output Parameter:
10589b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
10599b94acceSBarry Smith 
1060c96a6f78SLois Curfman McInnes    Notes:
1061c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1062c96a6f78SLois Curfman McInnes 
106336851e7fSLois Curfman McInnes    Level: intermediate
106436851e7fSLois Curfman McInnes 
10659b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
106658ebbce7SBarry Smith 
1067e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
106858ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
10699b94acceSBarry Smith @*/
10707087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
10719b94acceSBarry Smith {
10723a40ed3dSBarry Smith   PetscFunctionBegin;
10730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10744482741eSBarry Smith   PetscValidIntPointer(nfails,2);
107550ffb88aSMatthew Knepley   *nfails = snes->numFailures;
107650ffb88aSMatthew Knepley   PetscFunctionReturn(0);
107750ffb88aSMatthew Knepley }
107850ffb88aSMatthew Knepley 
107950ffb88aSMatthew Knepley #undef __FUNCT__
1080b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
108150ffb88aSMatthew Knepley /*@
1082b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
108350ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
108450ffb88aSMatthew Knepley 
108550ffb88aSMatthew Knepley    Not Collective
108650ffb88aSMatthew Knepley 
108750ffb88aSMatthew Knepley    Input Parameters:
108850ffb88aSMatthew Knepley +  snes     - SNES context
108950ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
109050ffb88aSMatthew Knepley 
109150ffb88aSMatthew Knepley    Level: intermediate
109250ffb88aSMatthew Knepley 
109350ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
109458ebbce7SBarry Smith 
1095e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
109658ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
109750ffb88aSMatthew Knepley @*/
10987087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
109950ffb88aSMatthew Knepley {
110050ffb88aSMatthew Knepley   PetscFunctionBegin;
11010700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
110250ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
110350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
110450ffb88aSMatthew Knepley }
110550ffb88aSMatthew Knepley 
110650ffb88aSMatthew Knepley #undef __FUNCT__
1107b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
110850ffb88aSMatthew Knepley /*@
1109b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
111050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
111150ffb88aSMatthew Knepley 
111250ffb88aSMatthew Knepley    Not Collective
111350ffb88aSMatthew Knepley 
111450ffb88aSMatthew Knepley    Input Parameter:
111550ffb88aSMatthew Knepley .  snes     - SNES context
111650ffb88aSMatthew Knepley 
111750ffb88aSMatthew Knepley    Output Parameter:
111850ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
111950ffb88aSMatthew Knepley 
112050ffb88aSMatthew Knepley    Level: intermediate
112150ffb88aSMatthew Knepley 
112250ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
112358ebbce7SBarry Smith 
1124e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
112558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
112658ebbce7SBarry Smith 
112750ffb88aSMatthew Knepley @*/
11287087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
112950ffb88aSMatthew Knepley {
113050ffb88aSMatthew Knepley   PetscFunctionBegin;
11310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11324482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
113350ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
11343a40ed3dSBarry Smith   PetscFunctionReturn(0);
11359b94acceSBarry Smith }
1136a847f771SSatish Balay 
11374a2ae208SSatish Balay #undef __FUNCT__
11382541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
11392541af92SBarry Smith /*@
11402541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
11412541af92SBarry Smith      done by SNES.
11422541af92SBarry Smith 
11432541af92SBarry Smith    Not Collective
11442541af92SBarry Smith 
11452541af92SBarry Smith    Input Parameter:
11462541af92SBarry Smith .  snes     - SNES context
11472541af92SBarry Smith 
11482541af92SBarry Smith    Output Parameter:
11492541af92SBarry Smith .  nfuncs - number of evaluations
11502541af92SBarry Smith 
11512541af92SBarry Smith    Level: intermediate
11522541af92SBarry Smith 
11532541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
115458ebbce7SBarry Smith 
1155e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
11562541af92SBarry Smith @*/
11577087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
11582541af92SBarry Smith {
11592541af92SBarry Smith   PetscFunctionBegin;
11600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11612541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
11622541af92SBarry Smith   *nfuncs = snes->nfuncs;
11632541af92SBarry Smith   PetscFunctionReturn(0);
11642541af92SBarry Smith }
11652541af92SBarry Smith 
11662541af92SBarry Smith #undef __FUNCT__
11673d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
11683d4c4710SBarry Smith /*@
11693d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
11703d4c4710SBarry Smith    linear solvers.
11713d4c4710SBarry Smith 
11723d4c4710SBarry Smith    Not Collective
11733d4c4710SBarry Smith 
11743d4c4710SBarry Smith    Input Parameter:
11753d4c4710SBarry Smith .  snes - SNES context
11763d4c4710SBarry Smith 
11773d4c4710SBarry Smith    Output Parameter:
11783d4c4710SBarry Smith .  nfails - number of failed solves
11793d4c4710SBarry Smith 
11803d4c4710SBarry Smith    Notes:
11813d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
11823d4c4710SBarry Smith 
11833d4c4710SBarry Smith    Level: intermediate
11843d4c4710SBarry Smith 
11853d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
118658ebbce7SBarry Smith 
1187e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
11883d4c4710SBarry Smith @*/
11897087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
11903d4c4710SBarry Smith {
11913d4c4710SBarry Smith   PetscFunctionBegin;
11920700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11933d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
11943d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
11953d4c4710SBarry Smith   PetscFunctionReturn(0);
11963d4c4710SBarry Smith }
11973d4c4710SBarry Smith 
11983d4c4710SBarry Smith #undef __FUNCT__
11993d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
12003d4c4710SBarry Smith /*@
12013d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
12023d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
12033d4c4710SBarry Smith 
12043f9fe445SBarry Smith    Logically Collective on SNES
12053d4c4710SBarry Smith 
12063d4c4710SBarry Smith    Input Parameters:
12073d4c4710SBarry Smith +  snes     - SNES context
12083d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
12093d4c4710SBarry Smith 
12103d4c4710SBarry Smith    Level: intermediate
12113d4c4710SBarry Smith 
1212a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
12133d4c4710SBarry Smith 
12143d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
12153d4c4710SBarry Smith 
121658ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
12173d4c4710SBarry Smith @*/
12187087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
12193d4c4710SBarry Smith {
12203d4c4710SBarry Smith   PetscFunctionBegin;
12210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1222c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
12233d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
12243d4c4710SBarry Smith   PetscFunctionReturn(0);
12253d4c4710SBarry Smith }
12263d4c4710SBarry Smith 
12273d4c4710SBarry Smith #undef __FUNCT__
12283d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
12293d4c4710SBarry Smith /*@
12303d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
12313d4c4710SBarry Smith      are allowed before SNES terminates
12323d4c4710SBarry Smith 
12333d4c4710SBarry Smith    Not Collective
12343d4c4710SBarry Smith 
12353d4c4710SBarry Smith    Input Parameter:
12363d4c4710SBarry Smith .  snes     - SNES context
12373d4c4710SBarry Smith 
12383d4c4710SBarry Smith    Output Parameter:
12393d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
12403d4c4710SBarry Smith 
12413d4c4710SBarry Smith    Level: intermediate
12423d4c4710SBarry Smith 
12433d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
12443d4c4710SBarry Smith 
12453d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
12463d4c4710SBarry Smith 
1247e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
12483d4c4710SBarry Smith @*/
12497087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
12503d4c4710SBarry Smith {
12513d4c4710SBarry Smith   PetscFunctionBegin;
12520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12533d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
12543d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
12553d4c4710SBarry Smith   PetscFunctionReturn(0);
12563d4c4710SBarry Smith }
12573d4c4710SBarry Smith 
12583d4c4710SBarry Smith #undef __FUNCT__
1259b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1260c96a6f78SLois Curfman McInnes /*@
1261b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1262c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1263c96a6f78SLois Curfman McInnes 
1264c7afd0dbSLois Curfman McInnes    Not Collective
1265c7afd0dbSLois Curfman McInnes 
1266c96a6f78SLois Curfman McInnes    Input Parameter:
1267c96a6f78SLois Curfman McInnes .  snes - SNES context
1268c96a6f78SLois Curfman McInnes 
1269c96a6f78SLois Curfman McInnes    Output Parameter:
1270c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1271c96a6f78SLois Curfman McInnes 
1272c96a6f78SLois Curfman McInnes    Notes:
1273c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1274c96a6f78SLois Curfman McInnes 
127536851e7fSLois Curfman McInnes    Level: intermediate
127636851e7fSLois Curfman McInnes 
1277c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
12782b668275SBarry Smith 
12798c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1280c96a6f78SLois Curfman McInnes @*/
12817087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1282c96a6f78SLois Curfman McInnes {
12833a40ed3dSBarry Smith   PetscFunctionBegin;
12840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12854482741eSBarry Smith   PetscValidIntPointer(lits,2);
1286c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
12873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1288c96a6f78SLois Curfman McInnes }
1289c96a6f78SLois Curfman McInnes 
12904a2ae208SSatish Balay #undef __FUNCT__
129194b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
129252baeb72SSatish Balay /*@
129394b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
12949b94acceSBarry Smith 
129594b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1296c7afd0dbSLois Curfman McInnes 
12979b94acceSBarry Smith    Input Parameter:
12989b94acceSBarry Smith .  snes - the SNES context
12999b94acceSBarry Smith 
13009b94acceSBarry Smith    Output Parameter:
130194b7f48cSBarry Smith .  ksp - the KSP context
13029b94acceSBarry Smith 
13039b94acceSBarry Smith    Notes:
130494b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
13059b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
13062999313aSBarry Smith    PC contexts as well.
13079b94acceSBarry Smith 
130836851e7fSLois Curfman McInnes    Level: beginner
130936851e7fSLois Curfman McInnes 
131094b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
13119b94acceSBarry Smith 
13122999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
13139b94acceSBarry Smith @*/
13147087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
13159b94acceSBarry Smith {
13161cee3971SBarry Smith   PetscErrorCode ierr;
13171cee3971SBarry Smith 
13183a40ed3dSBarry Smith   PetscFunctionBegin;
13190700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13204482741eSBarry Smith   PetscValidPointer(ksp,2);
13211cee3971SBarry Smith 
13221cee3971SBarry Smith   if (!snes->ksp) {
13231cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
13241cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
13251cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
13261cee3971SBarry Smith   }
132794b7f48cSBarry Smith   *ksp = snes->ksp;
13283a40ed3dSBarry Smith   PetscFunctionReturn(0);
13299b94acceSBarry Smith }
133082bf6240SBarry Smith 
13314a2ae208SSatish Balay #undef __FUNCT__
13322999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
13332999313aSBarry Smith /*@
13342999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
13352999313aSBarry Smith 
13362999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
13372999313aSBarry Smith 
13382999313aSBarry Smith    Input Parameters:
13392999313aSBarry Smith +  snes - the SNES context
13402999313aSBarry Smith -  ksp - the KSP context
13412999313aSBarry Smith 
13422999313aSBarry Smith    Notes:
13432999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
13442999313aSBarry Smith    so this routine is rarely needed.
13452999313aSBarry Smith 
13462999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
13472999313aSBarry Smith    decreased by one.
13482999313aSBarry Smith 
13492999313aSBarry Smith    Level: developer
13502999313aSBarry Smith 
13512999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
13522999313aSBarry Smith 
13532999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
13542999313aSBarry Smith @*/
13557087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
13562999313aSBarry Smith {
13572999313aSBarry Smith   PetscErrorCode ierr;
13582999313aSBarry Smith 
13592999313aSBarry Smith   PetscFunctionBegin;
13600700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
13610700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
13622999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
13637dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1364906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
13652999313aSBarry Smith   snes->ksp = ksp;
13662999313aSBarry Smith   PetscFunctionReturn(0);
13672999313aSBarry Smith }
13682999313aSBarry Smith 
13697adad957SLisandro Dalcin #if 0
13702999313aSBarry Smith #undef __FUNCT__
13714a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
13726849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1373e24b481bSBarry Smith {
1374e24b481bSBarry Smith   PetscFunctionBegin;
1375e24b481bSBarry Smith   PetscFunctionReturn(0);
1376e24b481bSBarry Smith }
13777adad957SLisandro Dalcin #endif
1378e24b481bSBarry Smith 
13799b94acceSBarry Smith /* -----------------------------------------------------------*/
13804a2ae208SSatish Balay #undef __FUNCT__
13814a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
138252baeb72SSatish Balay /*@
13839b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
13849b94acceSBarry Smith 
1385c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1386c7afd0dbSLois Curfman McInnes 
1387c7afd0dbSLois Curfman McInnes    Input Parameters:
1388906ed7ccSBarry Smith .  comm - MPI communicator
13899b94acceSBarry Smith 
13909b94acceSBarry Smith    Output Parameter:
13919b94acceSBarry Smith .  outsnes - the new SNES context
13929b94acceSBarry Smith 
1393c7afd0dbSLois Curfman McInnes    Options Database Keys:
1394c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1395c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1396c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1397c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1398c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1399c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1400c1f60f51SBarry Smith 
140136851e7fSLois Curfman McInnes    Level: beginner
140236851e7fSLois Curfman McInnes 
14039b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
14049b94acceSBarry Smith 
1405a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1406a8054027SBarry Smith 
14079b94acceSBarry Smith @*/
14087087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
14099b94acceSBarry Smith {
1410dfbe8321SBarry Smith   PetscErrorCode      ierr;
14119b94acceSBarry Smith   SNES                snes;
1412fa9f3622SBarry Smith   SNESKSPEW           *kctx;
141337fcc0dbSBarry Smith 
14143a40ed3dSBarry Smith   PetscFunctionBegin;
1415ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
14168ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
14178ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
14188ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
14198ba1e511SMatthew Knepley #endif
14208ba1e511SMatthew Knepley 
14213194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
14227adad957SLisandro Dalcin 
142385385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
14242c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
142588976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
14269b94acceSBarry Smith   snes->max_its           = 50;
14279750a799SBarry Smith   snes->max_funcs         = 10000;
14289b94acceSBarry Smith   snes->norm              = 0.0;
1429fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1430b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1431b4874afaSBarry Smith   snes->ttol              = 0.0;
143270441072SBarry Smith   snes->abstol            = 1.e-50;
1433c60f73f4SPeter Brune   snes->stol              = 1.e-8;
14344b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
14359b94acceSBarry Smith   snes->nfuncs            = 0;
143650ffb88aSMatthew Knepley   snes->numFailures       = 0;
143750ffb88aSMatthew Knepley   snes->maxFailures       = 1;
14387a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1439e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1440a8054027SBarry Smith   snes->lagpreconditioner = 1;
1441639f9d9dSBarry Smith   snes->numbermonitors    = 0;
14429b94acceSBarry Smith   snes->data              = 0;
14434dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1444186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
14456f24a144SLois Curfman McInnes   snes->nwork             = 0;
144658c9b817SLisandro Dalcin   snes->work              = 0;
144758c9b817SLisandro Dalcin   snes->nvwork            = 0;
144858c9b817SLisandro Dalcin   snes->vwork             = 0;
1449758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1450758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1451758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1452758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1453758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1454e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1455e4ed7901SPeter Brune   snes->norm_init         = 0.;
1456e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1457184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
145889b92e6fSPeter Brune   snes->gssweeps          = 1;
14599b94acceSBarry Smith 
1460c40d0f55SPeter Brune   snes->pcside            = PC_RIGHT;
1461c40d0f55SPeter Brune 
1462d8f46077SPeter Brune   snes->mf                = PETSC_FALSE;
1463d8f46077SPeter Brune   snes->mf_operator       = PETSC_FALSE;
1464d8f46077SPeter Brune   snes->mf_version        = 1;
1465d8f46077SPeter Brune 
14663d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
14673d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
14683d4c4710SBarry Smith 
14699b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
147038f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
14719b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
14729b94acceSBarry Smith   kctx->version     = 2;
14739b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
14749b94acceSBarry Smith                              this was too large for some test cases */
147575567043SBarry Smith   kctx->rtol_last   = 0.0;
14769b94acceSBarry Smith   kctx->rtol_max    = .9;
14779b94acceSBarry Smith   kctx->gamma       = 1.0;
147862d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
147971f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
14809b94acceSBarry Smith   kctx->threshold   = .1;
148175567043SBarry Smith   kctx->lresid_last = 0.0;
148275567043SBarry Smith   kctx->norm_last   = 0.0;
14839b94acceSBarry Smith 
14849b94acceSBarry Smith   *outsnes = snes;
14853a40ed3dSBarry Smith   PetscFunctionReturn(0);
14869b94acceSBarry Smith }
14879b94acceSBarry Smith 
14884a2ae208SSatish Balay #undef __FUNCT__
14894a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
14909b94acceSBarry Smith /*@C
14919b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
14929b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
14939b94acceSBarry Smith    equations.
14949b94acceSBarry Smith 
14953f9fe445SBarry Smith    Logically Collective on SNES
1496fee21e36SBarry Smith 
1497c7afd0dbSLois Curfman McInnes    Input Parameters:
1498c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1499c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1500de044059SHong Zhang .  func - function evaluation routine
1501c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1502c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
15039b94acceSBarry Smith 
1504c7afd0dbSLois Curfman McInnes    Calling sequence of func:
15058d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1506c7afd0dbSLois Curfman McInnes 
1507c586c404SJed Brown +  snes - the SNES context
1508c586c404SJed Brown .  x - state at which to evaluate residual
1509c586c404SJed Brown .  f - vector to put residual
1510c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
15119b94acceSBarry Smith 
15129b94acceSBarry Smith    Notes:
15139b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
15149b94acceSBarry Smith $      f'(x) x = -f(x),
1515c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
15169b94acceSBarry Smith 
151736851e7fSLois Curfman McInnes    Level: beginner
151836851e7fSLois Curfman McInnes 
15199b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
15209b94acceSBarry Smith 
15218b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
15229b94acceSBarry Smith @*/
15237087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
15249b94acceSBarry Smith {
152585385478SLisandro Dalcin   PetscErrorCode ierr;
15266cab3a1bSJed Brown   DM             dm;
15276cab3a1bSJed Brown 
15283a40ed3dSBarry Smith   PetscFunctionBegin;
15290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1530d2a683ecSLisandro Dalcin   if (r) {
1531d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1532d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
153385385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
15346bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
153585385478SLisandro Dalcin     snes->vec_func = r;
1536d2a683ecSLisandro Dalcin   }
15376cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15386cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
15393a40ed3dSBarry Smith   PetscFunctionReturn(0);
15409b94acceSBarry Smith }
15419b94acceSBarry Smith 
1542646217ecSPeter Brune 
1543646217ecSPeter Brune #undef __FUNCT__
1544e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1545e4ed7901SPeter Brune /*@C
1546e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1547e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1548e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1549e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1550e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1551e4ed7901SPeter Brune 
1552e4ed7901SPeter Brune    Logically Collective on SNES
1553e4ed7901SPeter Brune 
1554e4ed7901SPeter Brune    Input Parameters:
1555e4ed7901SPeter Brune +  snes - the SNES context
1556e4ed7901SPeter Brune -  f - vector to store function value
1557e4ed7901SPeter Brune 
1558e4ed7901SPeter Brune    Notes:
1559e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1560e4ed7901SPeter Brune 
1561e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1562e4ed7901SPeter Brune 
1563e4ed7901SPeter Brune    Level: developer
1564e4ed7901SPeter Brune 
1565e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1566e4ed7901SPeter Brune 
1567e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1568e4ed7901SPeter Brune @*/
1569e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1570e4ed7901SPeter Brune {
1571e4ed7901SPeter Brune   PetscErrorCode ierr;
1572e4ed7901SPeter Brune   Vec            vec_func;
1573e4ed7901SPeter Brune 
1574e4ed7901SPeter Brune   PetscFunctionBegin;
1575e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1576e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1577e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1578e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1579e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1580217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1581e4ed7901SPeter Brune   PetscFunctionReturn(0);
1582e4ed7901SPeter Brune }
1583e4ed7901SPeter Brune 
1584e4ed7901SPeter Brune 
1585e4ed7901SPeter Brune #undef __FUNCT__
1586e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1587e4ed7901SPeter Brune /*@C
1588e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1589e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1590e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1591e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1592e4ed7901SPeter Brune 
1593e4ed7901SPeter Brune    Logically Collective on SNES
1594e4ed7901SPeter Brune 
1595e4ed7901SPeter Brune    Input Parameters:
1596e4ed7901SPeter Brune +  snes - the SNES context
1597e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1598e4ed7901SPeter Brune 
1599e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1600e4ed7901SPeter Brune 
1601e4ed7901SPeter Brune    Level: developer
1602e4ed7901SPeter Brune 
1603e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1604e4ed7901SPeter Brune 
1605e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1606e4ed7901SPeter Brune @*/
1607e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1608e4ed7901SPeter Brune {
1609e4ed7901SPeter Brune   PetscFunctionBegin;
1610e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1611e4ed7901SPeter Brune   snes->norm_init = fnorm;
1612e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1613e4ed7901SPeter Brune   PetscFunctionReturn(0);
1614e4ed7901SPeter Brune }
1615e4ed7901SPeter Brune 
1616e4ed7901SPeter Brune #undef __FUNCT__
1617534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1618534ebe21SPeter Brune /*@
1619534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1620534ebe21SPeter Brune    of the SNES method.
1621534ebe21SPeter Brune 
1622534ebe21SPeter Brune    Logically Collective on SNES
1623534ebe21SPeter Brune 
1624534ebe21SPeter Brune    Input Parameters:
1625534ebe21SPeter Brune +  snes - the SNES context
1626534ebe21SPeter Brune -  normtype - the type of the norm used
1627534ebe21SPeter Brune 
1628534ebe21SPeter Brune    Notes:
1629534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1630534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1631534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1632534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1633534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1634534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1635534ebe21SPeter Brune    their solution.
1636534ebe21SPeter Brune 
1637534ebe21SPeter Brune    Level: developer
1638534ebe21SPeter Brune 
1639534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1640534ebe21SPeter Brune 
1641534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1642534ebe21SPeter Brune @*/
1643534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1644534ebe21SPeter Brune {
1645534ebe21SPeter Brune   PetscFunctionBegin;
1646534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1647534ebe21SPeter Brune   snes->normtype = normtype;
1648534ebe21SPeter Brune   PetscFunctionReturn(0);
1649534ebe21SPeter Brune }
1650534ebe21SPeter Brune 
1651534ebe21SPeter Brune 
1652534ebe21SPeter Brune #undef __FUNCT__
1653534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1654534ebe21SPeter Brune /*@
1655534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1656534ebe21SPeter Brune    of the SNES method.
1657534ebe21SPeter Brune 
1658534ebe21SPeter Brune    Logically Collective on SNES
1659534ebe21SPeter Brune 
1660534ebe21SPeter Brune    Input Parameters:
1661534ebe21SPeter Brune +  snes - the SNES context
1662534ebe21SPeter Brune -  normtype - the type of the norm used
1663534ebe21SPeter Brune 
1664534ebe21SPeter Brune    Level: advanced
1665534ebe21SPeter Brune 
1666534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1667534ebe21SPeter Brune 
1668534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1669534ebe21SPeter Brune @*/
1670534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1671534ebe21SPeter Brune {
1672534ebe21SPeter Brune   PetscFunctionBegin;
1673534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1674534ebe21SPeter Brune   *normtype = snes->normtype;
1675534ebe21SPeter Brune   PetscFunctionReturn(0);
1676534ebe21SPeter Brune }
1677534ebe21SPeter Brune 
1678534ebe21SPeter Brune #undef __FUNCT__
1679646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1680c79ef259SPeter Brune /*@C
1681c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1682c79ef259SPeter Brune    use with composed nonlinear solvers.
1683c79ef259SPeter Brune 
1684c79ef259SPeter Brune    Input Parameters:
1685c79ef259SPeter Brune +  snes   - the SNES context
1686c79ef259SPeter Brune .  gsfunc - function evaluation routine
1687c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1688c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1689c79ef259SPeter Brune 
1690c79ef259SPeter Brune    Calling sequence of func:
1691c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1692c79ef259SPeter Brune 
1693c79ef259SPeter Brune +  X   - solution vector
1694c79ef259SPeter Brune .  B   - RHS vector
1695d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1696c79ef259SPeter Brune 
1697c79ef259SPeter Brune    Notes:
1698c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1699c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1700c79ef259SPeter Brune 
1701d28543b3SPeter Brune    Level: intermediate
1702c79ef259SPeter Brune 
1703d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1704c79ef259SPeter Brune 
1705c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1706c79ef259SPeter Brune @*/
17076cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
17086cab3a1bSJed Brown {
17096cab3a1bSJed Brown   PetscErrorCode ierr;
17106cab3a1bSJed Brown   DM             dm;
17116cab3a1bSJed Brown 
1712646217ecSPeter Brune   PetscFunctionBegin;
17136cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17146cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17156cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1716646217ecSPeter Brune   PetscFunctionReturn(0);
1717646217ecSPeter Brune }
1718646217ecSPeter Brune 
1719d25893d9SBarry Smith #undef __FUNCT__
172089b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
172189b92e6fSPeter Brune /*@
172289b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
172389b92e6fSPeter Brune 
172489b92e6fSPeter Brune    Input Parameters:
172589b92e6fSPeter Brune +  snes   - the SNES context
172689b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
172789b92e6fSPeter Brune 
172889b92e6fSPeter Brune    Level: intermediate
172989b92e6fSPeter Brune 
173089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
173189b92e6fSPeter Brune 
173289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
173389b92e6fSPeter Brune @*/
173489b92e6fSPeter Brune 
1735c35f09e5SBarry Smith PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps)
1736c35f09e5SBarry Smith {
173789b92e6fSPeter Brune   PetscFunctionBegin;
173889b92e6fSPeter Brune   snes->gssweeps = sweeps;
173989b92e6fSPeter Brune   PetscFunctionReturn(0);
174089b92e6fSPeter Brune }
174189b92e6fSPeter Brune 
174289b92e6fSPeter Brune 
174389b92e6fSPeter Brune #undef __FUNCT__
174489b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
174589b92e6fSPeter Brune /*@
174689b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
174789b92e6fSPeter Brune 
174889b92e6fSPeter Brune    Input Parameters:
174989b92e6fSPeter Brune .  snes   - the SNES context
175089b92e6fSPeter Brune 
175189b92e6fSPeter Brune    Output Parameters:
175289b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
175389b92e6fSPeter Brune 
175489b92e6fSPeter Brune    Level: intermediate
175589b92e6fSPeter Brune 
175689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
175789b92e6fSPeter Brune 
175889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
175989b92e6fSPeter Brune @*/
1760c35f09e5SBarry Smith PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps)
1761c35f09e5SBarry Smith {
176289b92e6fSPeter Brune   PetscFunctionBegin;
176389b92e6fSPeter Brune   *sweeps = snes->gssweeps;
176489b92e6fSPeter Brune   PetscFunctionReturn(0);
176589b92e6fSPeter Brune }
176689b92e6fSPeter Brune 
176789b92e6fSPeter Brune #undef __FUNCT__
17688b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
17698b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
17708b0a5094SBarry Smith {
17718b0a5094SBarry Smith   PetscErrorCode ierr;
1772e03ab78fSPeter Brune   DM             dm;
1773942e3340SBarry Smith   DMSNES         sdm;
17746cab3a1bSJed Brown 
17758b0a5094SBarry Smith   PetscFunctionBegin;
1776e03ab78fSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
1777942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
17788b0a5094SBarry Smith   /*  A(x)*x - b(x) */
177922c6f798SBarry Smith   if (sdm->ops->computepfunction) {
178022c6f798SBarry Smith     ierr = (*sdm->ops->computepfunction)(snes,x,f,sdm->pctx);CHKERRQ(ierr);
178122c6f798SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard function.");
1782e03ab78fSPeter Brune 
178322c6f798SBarry Smith   if (sdm->ops->computepjacobian) {
178422c6f798SBarry Smith     ierr = (*sdm->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,sdm->pctx);CHKERRQ(ierr);
178574e1e8c1SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard matrix.");
17868b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
1787*95eabcedSBarry Smith   ierr = MatMultAdd(snes->jacobian,x,f,f);CHKERRQ(ierr);
1788*95eabcedSBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
17898b0a5094SBarry Smith   PetscFunctionReturn(0);
17908b0a5094SBarry Smith }
17918b0a5094SBarry Smith 
17928b0a5094SBarry Smith #undef __FUNCT__
17938b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
17948b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
17958b0a5094SBarry Smith {
17968b0a5094SBarry Smith   PetscFunctionBegin;
1797e03ab78fSPeter Brune   /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */
17988b0a5094SBarry Smith   *flag = snes->matstruct;
17998b0a5094SBarry Smith   PetscFunctionReturn(0);
18008b0a5094SBarry Smith }
18018b0a5094SBarry Smith 
18028b0a5094SBarry Smith #undef __FUNCT__
18038b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
18048b0a5094SBarry Smith /*@C
18050d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
18068b0a5094SBarry Smith 
18078b0a5094SBarry Smith    Logically Collective on SNES
18088b0a5094SBarry Smith 
18098b0a5094SBarry Smith    Input Parameters:
18108b0a5094SBarry Smith +  snes - the SNES context
18118b0a5094SBarry Smith .  r - vector to store function value
18128b0a5094SBarry Smith .  func - function evaluation routine
18138b0a5094SBarry Smith .  jmat - normally the same as mat but you can pass another matrix for which you compute the Jacobian of A(x) x - b(x) (see jmat below)
18148b0a5094SBarry Smith .  mat - matrix to store A
18158b0a5094SBarry Smith .  mfunc  - function to compute matrix value
18168b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
18178b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
18188b0a5094SBarry Smith 
18198b0a5094SBarry Smith    Calling sequence of func:
18208b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
18218b0a5094SBarry Smith 
18228b0a5094SBarry Smith +  f - function vector
18238b0a5094SBarry Smith -  ctx - optional user-defined function context
18248b0a5094SBarry Smith 
18258b0a5094SBarry Smith    Calling sequence of mfunc:
18268b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
18278b0a5094SBarry Smith 
18288b0a5094SBarry Smith +  x - input vector
18298b0a5094SBarry Smith .  jmat - Form Jacobian matrix of A(x) x - b(x) if available, not there is really no reason to use it in this way since then you can just use SNESSetJacobian(),
18308b0a5094SBarry Smith           normally just pass mat in this location
18318b0a5094SBarry Smith .  mat - form A(x) matrix
18328b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
18338b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
18348b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
18358b0a5094SBarry Smith 
18368b0a5094SBarry Smith    Notes:
18378b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
18388b0a5094SBarry Smith 
18398b0a5094SBarry 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}
18408b0a5094SBarry 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.
18418b0a5094SBarry Smith 
18428b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
18438b0a5094SBarry Smith 
18440d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
18450d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
18468b0a5094SBarry Smith 
18478b0a5094SBarry 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
18488b0a5094SBarry 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
18498b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
18508b0a5094SBarry Smith 
18518b0a5094SBarry Smith    Level: beginner
18528b0a5094SBarry Smith 
18538b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
18548b0a5094SBarry Smith 
18550d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
18568b0a5094SBarry Smith @*/
18578b0a5094SBarry Smith PetscErrorCode  SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),Mat jmat, Mat mat, PetscErrorCode (*mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
18588b0a5094SBarry Smith {
18598b0a5094SBarry Smith   PetscErrorCode ierr;
1860e03ab78fSPeter Brune   DM             dm;
1861e03ab78fSPeter Brune 
18628b0a5094SBarry Smith   PetscFunctionBegin;
18638b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1864e03ab78fSPeter Brune   ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
1865e03ab78fSPeter Brune   ierr = DMSNESSetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
18668b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
18678b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
18688b0a5094SBarry Smith   PetscFunctionReturn(0);
18698b0a5094SBarry Smith }
18708b0a5094SBarry Smith 
18717971a8bfSPeter Brune 
18727971a8bfSPeter Brune #undef __FUNCT__
18737971a8bfSPeter Brune #define __FUNCT__ "SNESGetPicard"
18747971a8bfSPeter Brune /*@C
18757971a8bfSPeter Brune    SNESGetPicard - Returns the context for the Picard iteration
18767971a8bfSPeter Brune 
18777971a8bfSPeter Brune    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
18787971a8bfSPeter Brune 
18797971a8bfSPeter Brune    Input Parameter:
18807971a8bfSPeter Brune .  snes - the SNES context
18817971a8bfSPeter Brune 
18827971a8bfSPeter Brune    Output Parameter:
18837971a8bfSPeter Brune +  r - the function (or PETSC_NULL)
18847971a8bfSPeter Brune .  func - the function (or PETSC_NULL)
18857971a8bfSPeter Brune .  jmat - the picard matrix (or PETSC_NULL)
18867971a8bfSPeter Brune .  mat  - the picard preconditioner matrix (or PETSC_NULL)
18877971a8bfSPeter Brune .  mfunc - the function for matrix evaluation (or PETSC_NULL)
18887971a8bfSPeter Brune -  ctx - the function context (or PETSC_NULL)
18897971a8bfSPeter Brune 
18907971a8bfSPeter Brune    Level: advanced
18917971a8bfSPeter Brune 
18927971a8bfSPeter Brune .keywords: SNES, nonlinear, get, function
18937971a8bfSPeter Brune 
18947971a8bfSPeter Brune .seealso: SNESSetPicard, SNESGetFunction, SNESGetJacobian, SNESGetDM
18957971a8bfSPeter Brune @*/
18967971a8bfSPeter Brune PetscErrorCode  SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),Mat *jmat, Mat *mat, PetscErrorCode (**mfunc)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
18977971a8bfSPeter Brune {
18987971a8bfSPeter Brune   PetscErrorCode ierr;
18997971a8bfSPeter Brune   DM             dm;
19007971a8bfSPeter Brune 
19017971a8bfSPeter Brune   PetscFunctionBegin;
19027971a8bfSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19037971a8bfSPeter Brune   ierr = SNESGetFunction(snes,r,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
19047971a8bfSPeter Brune   ierr = SNESGetJacobian(snes,jmat,mat,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
19057971a8bfSPeter Brune   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19067971a8bfSPeter Brune   ierr = DMSNESGetPicard(dm,func,mfunc,ctx);CHKERRQ(ierr);
19077971a8bfSPeter Brune   PetscFunctionReturn(0);
19087971a8bfSPeter Brune }
19097971a8bfSPeter Brune 
19108b0a5094SBarry Smith #undef __FUNCT__
1911d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1912d25893d9SBarry Smith /*@C
1913d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1914d25893d9SBarry Smith 
1915d25893d9SBarry Smith    Logically Collective on SNES
1916d25893d9SBarry Smith 
1917d25893d9SBarry Smith    Input Parameters:
1918d25893d9SBarry Smith +  snes - the SNES context
1919d25893d9SBarry Smith .  func - function evaluation routine
1920d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1921d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1922d25893d9SBarry Smith 
1923d25893d9SBarry Smith    Calling sequence of func:
1924d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1925d25893d9SBarry Smith 
1926d25893d9SBarry Smith .  f - function vector
1927d25893d9SBarry Smith -  ctx - optional user-defined function context
1928d25893d9SBarry Smith 
1929d25893d9SBarry Smith    Level: intermediate
1930d25893d9SBarry Smith 
1931d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1932d25893d9SBarry Smith 
1933d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1934d25893d9SBarry Smith @*/
1935d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1936d25893d9SBarry Smith {
1937d25893d9SBarry Smith   PetscFunctionBegin;
1938d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1939d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1940d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1941d25893d9SBarry Smith   PetscFunctionReturn(0);
1942d25893d9SBarry Smith }
1943d25893d9SBarry Smith 
19443ab0aad5SBarry Smith /* --------------------------------------------------------------- */
19453ab0aad5SBarry Smith #undef __FUNCT__
19461096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
19471096aae1SMatthew Knepley /*@C
19481096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
19491096aae1SMatthew Knepley    it assumes a zero right hand side.
19501096aae1SMatthew Knepley 
19513f9fe445SBarry Smith    Logically Collective on SNES
19521096aae1SMatthew Knepley 
19531096aae1SMatthew Knepley    Input Parameter:
19541096aae1SMatthew Knepley .  snes - the SNES context
19551096aae1SMatthew Knepley 
19561096aae1SMatthew Knepley    Output Parameter:
1957bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
19581096aae1SMatthew Knepley 
19591096aae1SMatthew Knepley    Level: intermediate
19601096aae1SMatthew Knepley 
19611096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
19621096aae1SMatthew Knepley 
196385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
19641096aae1SMatthew Knepley @*/
19657087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
19661096aae1SMatthew Knepley {
19671096aae1SMatthew Knepley   PetscFunctionBegin;
19680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19691096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
197085385478SLisandro Dalcin   *rhs = snes->vec_rhs;
19711096aae1SMatthew Knepley   PetscFunctionReturn(0);
19721096aae1SMatthew Knepley }
19731096aae1SMatthew Knepley 
19741096aae1SMatthew Knepley #undef __FUNCT__
19754a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
19769b94acceSBarry Smith /*@
197736851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
19789b94acceSBarry Smith                          SNESSetFunction().
19799b94acceSBarry Smith 
1980c7afd0dbSLois Curfman McInnes    Collective on SNES
1981c7afd0dbSLois Curfman McInnes 
19829b94acceSBarry Smith    Input Parameters:
1983c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1984c7afd0dbSLois Curfman McInnes -  x - input vector
19859b94acceSBarry Smith 
19869b94acceSBarry Smith    Output Parameter:
19873638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
19889b94acceSBarry Smith 
19891bffabb2SLois Curfman McInnes    Notes:
199036851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
199136851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
199236851e7fSLois Curfman McInnes    themselves.
199336851e7fSLois Curfman McInnes 
199436851e7fSLois Curfman McInnes    Level: developer
199536851e7fSLois Curfman McInnes 
19969b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
19979b94acceSBarry Smith 
1998a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
19999b94acceSBarry Smith @*/
20007087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
20019b94acceSBarry Smith {
2002dfbe8321SBarry Smith   PetscErrorCode ierr;
20036cab3a1bSJed Brown   DM             dm;
2004942e3340SBarry Smith   DMSNES         sdm;
20059b94acceSBarry Smith 
20063a40ed3dSBarry Smith   PetscFunctionBegin;
20070700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20080700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
20090700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
2010c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
2011c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
20124ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
2013184914b5SBarry Smith 
20146cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2015942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
2016d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
2017c40d0f55SPeter Brune   if (snes->pc && snes->pcside == PC_LEFT) {
2018c40d0f55SPeter Brune     ierr = VecCopy(x,y);CHKERRQ(ierr);
2019c40d0f55SPeter Brune     ierr = SNESSolve(snes->pc,snes->vec_rhs,y);CHKERRQ(ierr);
2020c40d0f55SPeter Brune     ierr = VecAYPX(y,-1.0,x);CHKERRQ(ierr);
202122c6f798SBarry Smith   } else if (sdm->ops->computefunction) {
2022d64ed03dSBarry Smith     PetscStackPush("SNES user function");
202322c6f798SBarry Smith     ierr = (*sdm->ops->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
2024d64ed03dSBarry Smith     PetscStackPop;
2025c90fad12SPeter Brune   } else if (snes->vec_rhs) {
2026c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
2027644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
202885385478SLisandro Dalcin   if (snes->vec_rhs) {
202985385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
20303ab0aad5SBarry Smith   }
2031ae3c334cSLois Curfman McInnes   snes->nfuncs++;
2032d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
20334ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
20343a40ed3dSBarry Smith   PetscFunctionReturn(0);
20359b94acceSBarry Smith }
20369b94acceSBarry Smith 
20374a2ae208SSatish Balay #undef __FUNCT__
2038646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
2039c79ef259SPeter Brune /*@
2040c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
2041c79ef259SPeter Brune                    SNESSetGS().
2042c79ef259SPeter Brune 
2043c79ef259SPeter Brune    Collective on SNES
2044c79ef259SPeter Brune 
2045c79ef259SPeter Brune    Input Parameters:
2046c79ef259SPeter Brune +  snes - the SNES context
2047c79ef259SPeter Brune .  x - input vector
2048c79ef259SPeter Brune -  b - rhs vector
2049c79ef259SPeter Brune 
2050c79ef259SPeter Brune    Output Parameter:
2051c79ef259SPeter Brune .  x - new solution vector
2052c79ef259SPeter Brune 
2053c79ef259SPeter Brune    Notes:
2054c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
2055c79ef259SPeter Brune    implementations, so most users would not generally call this routine
2056c79ef259SPeter Brune    themselves.
2057c79ef259SPeter Brune 
2058c79ef259SPeter Brune    Level: developer
2059c79ef259SPeter Brune 
2060c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
2061c79ef259SPeter Brune 
2062c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
2063c79ef259SPeter Brune @*/
2064646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
2065646217ecSPeter Brune {
2066646217ecSPeter Brune   PetscErrorCode ierr;
206789b92e6fSPeter Brune   PetscInt       i;
20686cab3a1bSJed Brown   DM             dm;
2069942e3340SBarry Smith   DMSNES         sdm;
2070646217ecSPeter Brune 
2071646217ecSPeter Brune   PetscFunctionBegin;
2072646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2073646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
2074646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
2075646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
2076646217ecSPeter Brune   if (b) PetscCheckSameComm(snes,1,b,3);
20774ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
2078701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
20796cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2080942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
208122c6f798SBarry Smith   if (sdm->ops->computegs) {
208289b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
2083646217ecSPeter Brune       PetscStackPush("SNES user GS");
208422c6f798SBarry Smith       ierr = (*sdm->ops->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
2085646217ecSPeter Brune       PetscStackPop;
208689b92e6fSPeter Brune     }
2087646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
2088701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
20894ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
2090646217ecSPeter Brune   PetscFunctionReturn(0);
2091646217ecSPeter Brune }
2092646217ecSPeter Brune 
2093646217ecSPeter Brune 
2094646217ecSPeter Brune #undef __FUNCT__
20954a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
209662fef451SLois Curfman McInnes /*@
209762fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
209862fef451SLois Curfman McInnes    set with SNESSetJacobian().
209962fef451SLois Curfman McInnes 
2100c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
2101c7afd0dbSLois Curfman McInnes 
210262fef451SLois Curfman McInnes    Input Parameters:
2103c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2104c7afd0dbSLois Curfman McInnes -  x - input vector
210562fef451SLois Curfman McInnes 
210662fef451SLois Curfman McInnes    Output Parameters:
2107c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
210862fef451SLois Curfman McInnes .  B - optional preconditioning matrix
21092b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
2110fee21e36SBarry Smith 
2111e35cf81dSBarry Smith   Options Database Keys:
2112e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
2113693365a8SJed Brown .    -snes_lag_jacobian <lag>
2114693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
2115693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
2116693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
21174c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
2118c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
2119c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
2120c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
2121c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
2122c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
21234c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
2124c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
2125c01495d3SJed Brown 
2126e35cf81dSBarry Smith 
212762fef451SLois Curfman McInnes    Notes:
212862fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
212962fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
213062fef451SLois Curfman McInnes 
213194b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
2132dc5a77f8SLois Curfman McInnes    flag parameter.
213362fef451SLois Curfman McInnes 
213436851e7fSLois Curfman McInnes    Level: developer
213536851e7fSLois Curfman McInnes 
213662fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
213762fef451SLois Curfman McInnes 
2138e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
213962fef451SLois Curfman McInnes @*/
21407087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
21419b94acceSBarry Smith {
2142dfbe8321SBarry Smith   PetscErrorCode ierr;
2143ace3abfcSBarry Smith   PetscBool      flag;
21446cab3a1bSJed Brown   DM             dm;
2145942e3340SBarry Smith   DMSNES         sdm;
21463a40ed3dSBarry Smith 
21473a40ed3dSBarry Smith   PetscFunctionBegin;
21480700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21490700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
21504482741eSBarry Smith   PetscValidPointer(flg,5);
2151c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
21524ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
21536cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2154942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
21553232da50SPeter Brune 
215622c6f798SBarry Smith   if (!sdm->ops->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
2157ebd3b9afSBarry Smith 
2158ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
2159ebd3b9afSBarry Smith 
2160fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
2161fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
2162fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
2163fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
2164e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2165e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
2166251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2167ebd3b9afSBarry Smith     if (flag) {
2168ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2169ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2170ebd3b9afSBarry Smith     }
2171e35cf81dSBarry Smith     PetscFunctionReturn(0);
2172e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
2173e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
2174e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
2175251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
2176ebd3b9afSBarry Smith     if (flag) {
2177ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2178ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
2179ebd3b9afSBarry Smith     }
2180e35cf81dSBarry Smith     PetscFunctionReturn(0);
2181e35cf81dSBarry Smith   }
2182e35cf81dSBarry Smith 
2183c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
2184e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
21853232da50SPeter Brune 
2186d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
218722c6f798SBarry Smith   ierr = (*sdm->ops->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2188d64ed03dSBarry Smith   PetscStackPop;
21893232da50SPeter Brune 
2190d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2191a8054027SBarry Smith 
21923b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
21933b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
21943b4f5425SBarry Smith     snes->lagpreconditioner = -1;
21953b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2196a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2197a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2198a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2199a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2200a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2201a8054027SBarry Smith   }
2202a8054027SBarry Smith 
22036d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
22040700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
22050700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2206693365a8SJed Brown   {
2207693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2208693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2209693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2210693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2211693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2212693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2213693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2214693365a8SJed Brown       MatStructure mstruct;
2215693365a8SJed Brown       PetscViewer vdraw,vstdout;
22166b3a5b13SJed Brown       PetscBool flg;
2217693365a8SJed Brown       if (flag_operator) {
2218693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2219693365a8SJed Brown         Bexp = Bexp_mine;
2220693365a8SJed Brown       } else {
2221693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2222251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2223693365a8SJed Brown         if (flg) Bexp = *B;
2224693365a8SJed Brown         else {
2225693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2226693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2227693365a8SJed Brown           Bexp = Bexp_mine;
2228693365a8SJed Brown         }
2229693365a8SJed Brown       }
2230693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2231693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2232693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2233693365a8SJed Brown       if (flag_draw || flag_contour) {
2234693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2235693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2236693365a8SJed Brown       } else vdraw = PETSC_NULL;
2237693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2238693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2239693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2240693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2241693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2242693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2243693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2244693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2245693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2246693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2247693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2248693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2249693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2250693365a8SJed Brown       }
2251693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2252693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2253693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2254693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2255693365a8SJed Brown     }
2256693365a8SJed Brown   }
22574c30e9fbSJed Brown   {
22586719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
22596719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
22604c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
22616719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
22624c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
22634c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
22646719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
22656719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
22666719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
22676719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
22684c30e9fbSJed Brown       Mat            Bfd;
22694c30e9fbSJed Brown       MatStructure   mstruct;
22704c30e9fbSJed Brown       PetscViewer    vdraw,vstdout;
22714c30e9fbSJed Brown       ISColoring     iscoloring;
22724c30e9fbSJed Brown       MatFDColoring  matfdcoloring;
22734c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
22744c30e9fbSJed Brown       void           *funcctx;
22756719d8e4SJed Brown       PetscReal      norm1,norm2,normmax;
22764c30e9fbSJed Brown 
22774c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
22784c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
22794c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
22804c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
22814c30e9fbSJed Brown 
22824c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
22834c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
22844c30e9fbSJed Brown         ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
22854c30e9fbSJed Brown         ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
22864c30e9fbSJed Brown         ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
22874c30e9fbSJed Brown         ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
22884c30e9fbSJed Brown         ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
22894c30e9fbSJed Brown         ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
22904c30e9fbSJed Brown 
22914c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
22924c30e9fbSJed Brown       if (flag_draw || flag_contour) {
22934c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
22944c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
22954c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
22964c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
22976719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
22984c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
22994c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
23006719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
23014c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
23024c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
23034c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
23046719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
23054c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
23066719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
23076719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
23084c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
23094c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
23104c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
23114c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
23124c30e9fbSJed Brown       }
23134c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
23146719d8e4SJed Brown 
23156719d8e4SJed Brown       if (flag_threshold) {
23166719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
23176719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
23186719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
23196719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
23206719d8e4SJed Brown           const PetscScalar *ba,*ca;
23216719d8e4SJed Brown           const PetscInt    *bj,*cj;
23226719d8e4SJed Brown           PetscInt          bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
23236719d8e4SJed Brown           PetscReal         maxentry = 0,maxdiff = 0,maxrdiff = 0;
23246719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
23256719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
23266719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
23276719d8e4SJed Brown           for (j=0; j<bn; j++) {
23286719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
23296719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
23306719d8e4SJed Brown               maxentrycol = bj[j];
23316719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
23326719d8e4SJed Brown             }
23336719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
23346719d8e4SJed Brown               maxdiffcol = bj[j];
23356719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
23366719d8e4SJed Brown             }
23376719d8e4SJed Brown             if (rdiff > maxrdiff) {
23386719d8e4SJed Brown               maxrdiffcol = bj[j];
23396719d8e4SJed Brown               maxrdiff = rdiff;
23406719d8e4SJed Brown             }
23416719d8e4SJed Brown           }
23426719d8e4SJed Brown           if (maxrdiff > 1) {
23436719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"row %D (maxentry=%G at %D, maxdiff=%G at %D, maxrdiff=%G at %D):",i,maxentry,maxentrycol,maxdiff,maxdiffcol,maxrdiff,maxrdiffcol);CHKERRQ(ierr);
23446719d8e4SJed Brown             for (j=0; j<bn; j++) {
23456719d8e4SJed Brown               PetscReal rdiff;
23466719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
23476719d8e4SJed Brown               if (rdiff > 1) {
23486719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
23496719d8e4SJed Brown               }
23506719d8e4SJed Brown             }
23516719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
23526719d8e4SJed Brown           }
23536719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
23546719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
23556719d8e4SJed Brown         }
23566719d8e4SJed Brown       }
23574c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
23584c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
23594c30e9fbSJed Brown     }
23604c30e9fbSJed Brown   }
23613a40ed3dSBarry Smith   PetscFunctionReturn(0);
23629b94acceSBarry Smith }
23639b94acceSBarry Smith 
23644a2ae208SSatish Balay #undef __FUNCT__
23654a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
23669b94acceSBarry Smith /*@C
23679b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2368044dda88SLois Curfman McInnes    location to store the matrix.
23699b94acceSBarry Smith 
23703f9fe445SBarry Smith    Logically Collective on SNES and Mat
2371c7afd0dbSLois Curfman McInnes 
23729b94acceSBarry Smith    Input Parameters:
2373c7afd0dbSLois Curfman McInnes +  snes - the SNES context
23749b94acceSBarry Smith .  A - Jacobian matrix
23759b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2376efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2377c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2378efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
23799b94acceSBarry Smith 
23809b94acceSBarry Smith    Calling sequence of func:
23818d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
23829b94acceSBarry Smith 
2383c7afd0dbSLois Curfman McInnes +  x - input vector
23849b94acceSBarry Smith .  A - Jacobian matrix
23859b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2386ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
23872b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2388c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
23899b94acceSBarry Smith 
23909b94acceSBarry Smith    Notes:
239194b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
23922cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2393ac21db08SLois Curfman McInnes 
2394ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
23959b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
23969b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
23979b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
23989b94acceSBarry Smith    throughout the global iterations.
23999b94acceSBarry Smith 
240016913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
240116913363SBarry Smith    each matrix.
240216913363SBarry Smith 
2403a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2404a8a26c1eSJed Brown    must be a MatFDColoring.
2405a8a26c1eSJed Brown 
2406c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2407c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2408c3cc8fd1SJed Brown 
240936851e7fSLois Curfman McInnes    Level: beginner
241036851e7fSLois Curfman McInnes 
24119b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
24129b94acceSBarry Smith 
24133ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
24149b94acceSBarry Smith @*/
24157087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
24169b94acceSBarry Smith {
2417dfbe8321SBarry Smith   PetscErrorCode ierr;
24186cab3a1bSJed Brown   DM             dm;
24193a7fca6bSBarry Smith 
24203a40ed3dSBarry Smith   PetscFunctionBegin;
24210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
24220700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
24230700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2424c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
242506975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
24266cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24276cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
24283a7fca6bSBarry Smith   if (A) {
24297dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
24306bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24319b94acceSBarry Smith     snes->jacobian = A;
24323a7fca6bSBarry Smith   }
24333a7fca6bSBarry Smith   if (B) {
24347dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
24356bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
24369b94acceSBarry Smith     snes->jacobian_pre = B;
24373a7fca6bSBarry Smith   }
24383a40ed3dSBarry Smith   PetscFunctionReturn(0);
24399b94acceSBarry Smith }
244062fef451SLois Curfman McInnes 
24414a2ae208SSatish Balay #undef __FUNCT__
24424a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2443c2aafc4cSSatish Balay /*@C
2444b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2445b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2446b4fd4287SBarry Smith 
2447c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2448c7afd0dbSLois Curfman McInnes 
2449b4fd4287SBarry Smith    Input Parameter:
2450b4fd4287SBarry Smith .  snes - the nonlinear solver context
2451b4fd4287SBarry Smith 
2452b4fd4287SBarry Smith    Output Parameters:
2453c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2454b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
245570e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
245670e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2457fee21e36SBarry Smith 
245836851e7fSLois Curfman McInnes    Level: advanced
245936851e7fSLois Curfman McInnes 
2460b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2461b4fd4287SBarry Smith @*/
24627087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2463b4fd4287SBarry Smith {
24646cab3a1bSJed Brown   PetscErrorCode ierr;
24656cab3a1bSJed Brown   DM             dm;
2466942e3340SBarry Smith   DMSNES         sdm;
24676cab3a1bSJed Brown 
24683a40ed3dSBarry Smith   PetscFunctionBegin;
24690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2470b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2471b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
24726cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2473942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
247422c6f798SBarry Smith   if (func) *func = sdm->ops->computejacobian;
24756cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
24763a40ed3dSBarry Smith   PetscFunctionReturn(0);
2477b4fd4287SBarry Smith }
2478b4fd4287SBarry Smith 
24799b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
24809b94acceSBarry Smith 
24814a2ae208SSatish Balay #undef __FUNCT__
24824a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
24839b94acceSBarry Smith /*@
24849b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2485272ac6f2SLois Curfman McInnes    of a nonlinear solver.
24869b94acceSBarry Smith 
2487fee21e36SBarry Smith    Collective on SNES
2488fee21e36SBarry Smith 
2489c7afd0dbSLois Curfman McInnes    Input Parameters:
249070e92668SMatthew Knepley .  snes - the SNES context
2491c7afd0dbSLois Curfman McInnes 
2492272ac6f2SLois Curfman McInnes    Notes:
2493272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2494272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2495272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2496272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2497272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2498272ac6f2SLois Curfman McInnes 
249936851e7fSLois Curfman McInnes    Level: advanced
250036851e7fSLois Curfman McInnes 
25019b94acceSBarry Smith .keywords: SNES, nonlinear, setup
25029b94acceSBarry Smith 
25039b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
25049b94acceSBarry Smith @*/
25057087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
25069b94acceSBarry Smith {
2507dfbe8321SBarry Smith   PetscErrorCode              ierr;
25086cab3a1bSJed Brown   DM                          dm;
2509942e3340SBarry Smith   DMSNES                      sdm;
2510c35f09e5SBarry Smith   SNESLineSearch              linesearch, pclinesearch;
25116e2a1849SPeter Brune   void                        *lsprectx,*lspostctx;
25126e2a1849SPeter Brune   SNESLineSearchPreCheckFunc  lsprefunc;
25136e2a1849SPeter Brune   SNESLineSearchPostCheckFunc lspostfunc;
25146e2a1849SPeter Brune   PetscErrorCode              (*func)(SNES,Vec,Vec,void*);
25156e2a1849SPeter Brune   Vec                         f,fpc;
25166e2a1849SPeter Brune   void                        *funcctx;
25176e2a1849SPeter Brune   PetscErrorCode              (*jac)(SNES,Vec,Mat*,Mat*,MatStructure*,void*);
25181eb13d49SPeter Brune   void                        *jacctx,*appctx;
25196e2a1849SPeter Brune   Mat                         A,B;
25203a40ed3dSBarry Smith 
25213a40ed3dSBarry Smith   PetscFunctionBegin;
25220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
25234dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
25249b94acceSBarry Smith 
25257adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
252685385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
252785385478SLisandro Dalcin   }
252885385478SLisandro Dalcin 
2529a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
253017186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
253158c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
253258c9b817SLisandro Dalcin 
253358c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
253458c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
253558c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
253658c9b817SLisandro Dalcin   }
253758c9b817SLisandro Dalcin 
25386cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
2539d8f46077SPeter Brune   ierr = DMShellSetGlobalVector(snes->dm,snes->vec_sol);CHKERRQ(ierr);
2540942e3340SBarry Smith   ierr = DMGetDMSNES(dm,&sdm);CHKERRQ(ierr);
254122c6f798SBarry Smith   if (!sdm->ops->computefunction) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object");
254222c6f798SBarry Smith   if (!sdm->ops->computejacobian) {
254319f7a02aSBarry Smith     ierr = DMSNESSetJacobian(dm,SNESDefaultComputeJacobianColor,PETSC_NULL);CHKERRQ(ierr);
254419f7a02aSBarry Smith   }
25456cab3a1bSJed Brown   if (!snes->vec_func) {
25466cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2547214df951SJed Brown   }
2548efd51863SBarry Smith 
2549b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2550b710008aSBarry Smith 
2551f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
25529e764e56SPeter Brune 
2553c40d0f55SPeter Brune   if (snes->pc && (snes->pcside == PC_LEFT)) snes->mf = PETSC_TRUE;
2554d8f46077SPeter Brune 
255528a52e04SBarry Smith   if (snes->mf) {
255628a52e04SBarry Smith     ierr = SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version);CHKERRQ(ierr);
255728a52e04SBarry Smith   }
2558d8f46077SPeter Brune 
2559d8f46077SPeter Brune 
2560d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2561d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2562d25893d9SBarry Smith   }
2563d25893d9SBarry Smith 
25646e2a1849SPeter Brune   if (snes->pc) {
25656e2a1849SPeter Brune     /* copy the DM over */
25666e2a1849SPeter Brune     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
25676e2a1849SPeter Brune     ierr = SNESSetDM(snes->pc,dm);CHKERRQ(ierr);
25686e2a1849SPeter Brune 
25696e2a1849SPeter Brune     ierr = SNESGetFunction(snes,&f,&func,&funcctx);CHKERRQ(ierr);
25706e2a1849SPeter Brune     ierr = VecDuplicate(f,&fpc);CHKERRQ(ierr);
25716e2a1849SPeter Brune     ierr = SNESSetFunction(snes->pc,fpc,func,funcctx);CHKERRQ(ierr);
25726e2a1849SPeter Brune     ierr = SNESGetJacobian(snes,&A,&B,&jac,&jacctx);CHKERRQ(ierr);
25736e2a1849SPeter Brune     ierr = SNESSetJacobian(snes->pc,A,B,jac,jacctx);CHKERRQ(ierr);
25741eb13d49SPeter Brune     ierr = SNESGetApplicationContext(snes,&appctx);CHKERRQ(ierr);
25751eb13d49SPeter Brune     ierr = SNESSetApplicationContext(snes->pc,appctx);CHKERRQ(ierr);
25766e2a1849SPeter Brune     ierr = VecDestroy(&fpc);CHKERRQ(ierr);
25776e2a1849SPeter Brune 
25786e2a1849SPeter Brune     /* copy the function pointers over */
25796e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->pc);CHKERRQ(ierr);
25806e2a1849SPeter Brune 
25816e2a1849SPeter Brune      /* default to 1 iteration */
2582140836e4SPeter Brune     ierr = SNESSetTolerances(snes->pc, 0.0, 0.0, 0.0, 1, snes->pc->max_funcs);CHKERRQ(ierr);
25836e2a1849SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
25846e2a1849SPeter Brune     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
25856e2a1849SPeter Brune 
25866e2a1849SPeter Brune     /* copy the line search context over */
25876e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&linesearch);CHKERRQ(ierr);
25886e2a1849SPeter Brune     ierr = SNESGetSNESLineSearch(snes->pc,&pclinesearch);CHKERRQ(ierr);
25896e2a1849SPeter Brune     ierr = SNESLineSearchGetPreCheck(linesearch,&lsprefunc,&lsprectx);CHKERRQ(ierr);
25906e2a1849SPeter Brune     ierr = SNESLineSearchGetPostCheck(linesearch,&lspostfunc,&lspostctx);CHKERRQ(ierr);
25916e2a1849SPeter Brune     ierr = SNESLineSearchSetPreCheck(pclinesearch,lsprefunc,lsprectx);CHKERRQ(ierr);
25926e2a1849SPeter Brune     ierr = SNESLineSearchSetPostCheck(pclinesearch,lspostfunc,lspostctx);CHKERRQ(ierr);
25936e2a1849SPeter Brune     ierr = PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch);CHKERRQ(ierr);
25946e2a1849SPeter Brune   }
25956e2a1849SPeter Brune 
2596410397dcSLisandro Dalcin   if (snes->ops->setup) {
2597410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2598410397dcSLisandro Dalcin   }
259958c9b817SLisandro Dalcin 
26007aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
26013a40ed3dSBarry Smith   PetscFunctionReturn(0);
26029b94acceSBarry Smith }
26039b94acceSBarry Smith 
26044a2ae208SSatish Balay #undef __FUNCT__
260537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
260637596af1SLisandro Dalcin /*@
260737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
260837596af1SLisandro Dalcin 
260937596af1SLisandro Dalcin    Collective on SNES
261037596af1SLisandro Dalcin 
261137596af1SLisandro Dalcin    Input Parameter:
261237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
261337596af1SLisandro Dalcin 
2614d25893d9SBarry Smith    Level: intermediate
2615d25893d9SBarry Smith 
2616d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
261737596af1SLisandro Dalcin 
261837596af1SLisandro Dalcin .keywords: SNES, destroy
261937596af1SLisandro Dalcin 
262037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
262137596af1SLisandro Dalcin @*/
262237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
262337596af1SLisandro Dalcin {
262437596af1SLisandro Dalcin   PetscErrorCode ierr;
262537596af1SLisandro Dalcin 
262637596af1SLisandro Dalcin   PetscFunctionBegin;
262737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2628d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2629d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2630d25893d9SBarry Smith     snes->user = PETSC_NULL;
2631d25893d9SBarry Smith   }
26328a23116dSBarry Smith   if (snes->pc) {
26338a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
26348a23116dSBarry Smith   }
26358a23116dSBarry Smith 
263637596af1SLisandro Dalcin   if (snes->ops->reset) {
263737596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
263837596af1SLisandro Dalcin   }
26399e764e56SPeter Brune   if (snes->ksp) {
26409e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
26419e764e56SPeter Brune   }
26429e764e56SPeter Brune 
26439e764e56SPeter Brune   if (snes->linesearch) {
2644f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
26459e764e56SPeter Brune   }
26469e764e56SPeter Brune 
26476bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
26486bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
26496bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
26506bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
26516bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
26526bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2653c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2654c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
265537596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
265637596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
265737596af1SLisandro Dalcin   PetscFunctionReturn(0);
265837596af1SLisandro Dalcin }
265937596af1SLisandro Dalcin 
266037596af1SLisandro Dalcin #undef __FUNCT__
26614a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
266252baeb72SSatish Balay /*@
26639b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
26649b94acceSBarry Smith    with SNESCreate().
26659b94acceSBarry Smith 
2666c7afd0dbSLois Curfman McInnes    Collective on SNES
2667c7afd0dbSLois Curfman McInnes 
26689b94acceSBarry Smith    Input Parameter:
26699b94acceSBarry Smith .  snes - the SNES context
26709b94acceSBarry Smith 
267136851e7fSLois Curfman McInnes    Level: beginner
267236851e7fSLois Curfman McInnes 
26739b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
26749b94acceSBarry Smith 
267563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
26769b94acceSBarry Smith @*/
26776bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
26789b94acceSBarry Smith {
26796849ba73SBarry Smith   PetscErrorCode ierr;
26803a40ed3dSBarry Smith 
26813a40ed3dSBarry Smith   PetscFunctionBegin;
26826bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
26836bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
26846bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2685d4bb536fSBarry Smith 
26866bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
26878a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
26886b8b9a38SLisandro Dalcin 
2689be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
26906bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
26916bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
26926d4c513bSLisandro Dalcin 
26936bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
26946bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2695f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
26966b8b9a38SLisandro Dalcin 
26976bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
26986bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
26996bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
27006b8b9a38SLisandro Dalcin   }
27016bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
27026bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
27036bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
270458c9b817SLisandro Dalcin   }
27056bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2706a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
27073a40ed3dSBarry Smith  PetscFunctionReturn(0);
27089b94acceSBarry Smith }
27099b94acceSBarry Smith 
27109b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
27119b94acceSBarry Smith 
27124a2ae208SSatish Balay #undef __FUNCT__
2713a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2714a8054027SBarry Smith /*@
2715a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2716a8054027SBarry Smith 
27173f9fe445SBarry Smith    Logically Collective on SNES
2718a8054027SBarry Smith 
2719a8054027SBarry Smith    Input Parameters:
2720a8054027SBarry Smith +  snes - the SNES context
2721a8054027SBarry 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
27223b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2723a8054027SBarry Smith 
2724a8054027SBarry Smith    Options Database Keys:
2725a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2726a8054027SBarry Smith 
2727a8054027SBarry Smith    Notes:
2728a8054027SBarry Smith    The default is 1
2729a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2730a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2731a8054027SBarry Smith 
2732a8054027SBarry Smith    Level: intermediate
2733a8054027SBarry Smith 
2734a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2735a8054027SBarry Smith 
2736e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2737a8054027SBarry Smith 
2738a8054027SBarry Smith @*/
27397087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2740a8054027SBarry Smith {
2741a8054027SBarry Smith   PetscFunctionBegin;
27420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2743e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2744e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2745c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2746a8054027SBarry Smith   snes->lagpreconditioner = lag;
2747a8054027SBarry Smith   PetscFunctionReturn(0);
2748a8054027SBarry Smith }
2749a8054027SBarry Smith 
2750a8054027SBarry Smith #undef __FUNCT__
2751efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2752efd51863SBarry Smith /*@
2753efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2754efd51863SBarry Smith 
2755efd51863SBarry Smith    Logically Collective on SNES
2756efd51863SBarry Smith 
2757efd51863SBarry Smith    Input Parameters:
2758efd51863SBarry Smith +  snes - the SNES context
2759efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2760efd51863SBarry Smith 
2761efd51863SBarry Smith    Options Database Keys:
2762efd51863SBarry Smith .    -snes_grid_sequence <steps>
2763efd51863SBarry Smith 
2764efd51863SBarry Smith    Level: intermediate
2765efd51863SBarry Smith 
2766c0df2a02SJed Brown    Notes:
2767c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2768c0df2a02SJed Brown 
2769efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2770efd51863SBarry Smith 
2771efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2772efd51863SBarry Smith 
2773efd51863SBarry Smith @*/
2774efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2775efd51863SBarry Smith {
2776efd51863SBarry Smith   PetscFunctionBegin;
2777efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2778efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2779efd51863SBarry Smith   snes->gridsequence = steps;
2780efd51863SBarry Smith   PetscFunctionReturn(0);
2781efd51863SBarry Smith }
2782efd51863SBarry Smith 
2783efd51863SBarry Smith #undef __FUNCT__
2784a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2785a8054027SBarry Smith /*@
2786a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2787a8054027SBarry Smith 
27883f9fe445SBarry Smith    Not Collective
2789a8054027SBarry Smith 
2790a8054027SBarry Smith    Input Parameter:
2791a8054027SBarry Smith .  snes - the SNES context
2792a8054027SBarry Smith 
2793a8054027SBarry Smith    Output Parameter:
2794a8054027SBarry 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
27953b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2796a8054027SBarry Smith 
2797a8054027SBarry Smith    Options Database Keys:
2798a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2799a8054027SBarry Smith 
2800a8054027SBarry Smith    Notes:
2801a8054027SBarry Smith    The default is 1
2802a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2803a8054027SBarry Smith 
2804a8054027SBarry Smith    Level: intermediate
2805a8054027SBarry Smith 
2806a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2807a8054027SBarry Smith 
2808a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2809a8054027SBarry Smith 
2810a8054027SBarry Smith @*/
28117087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2812a8054027SBarry Smith {
2813a8054027SBarry Smith   PetscFunctionBegin;
28140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2815a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2816a8054027SBarry Smith   PetscFunctionReturn(0);
2817a8054027SBarry Smith }
2818a8054027SBarry Smith 
2819a8054027SBarry Smith #undef __FUNCT__
2820e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2821e35cf81dSBarry Smith /*@
2822e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2823e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2824e35cf81dSBarry Smith 
28253f9fe445SBarry Smith    Logically Collective on SNES
2826e35cf81dSBarry Smith 
2827e35cf81dSBarry Smith    Input Parameters:
2828e35cf81dSBarry Smith +  snes - the SNES context
2829e35cf81dSBarry 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
2830fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2831e35cf81dSBarry Smith 
2832e35cf81dSBarry Smith    Options Database Keys:
2833e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2834e35cf81dSBarry Smith 
2835e35cf81dSBarry Smith    Notes:
2836e35cf81dSBarry Smith    The default is 1
2837e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2838fe3ffe1eSBarry 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
2839fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2840e35cf81dSBarry Smith 
2841e35cf81dSBarry Smith    Level: intermediate
2842e35cf81dSBarry Smith 
2843e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2844e35cf81dSBarry Smith 
2845e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2846e35cf81dSBarry Smith 
2847e35cf81dSBarry Smith @*/
28487087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2849e35cf81dSBarry Smith {
2850e35cf81dSBarry Smith   PetscFunctionBegin;
28510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2852e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2853e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2854c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2855e35cf81dSBarry Smith   snes->lagjacobian = lag;
2856e35cf81dSBarry Smith   PetscFunctionReturn(0);
2857e35cf81dSBarry Smith }
2858e35cf81dSBarry Smith 
2859e35cf81dSBarry Smith #undef __FUNCT__
2860e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2861e35cf81dSBarry Smith /*@
2862e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2863e35cf81dSBarry Smith 
28643f9fe445SBarry Smith    Not Collective
2865e35cf81dSBarry Smith 
2866e35cf81dSBarry Smith    Input Parameter:
2867e35cf81dSBarry Smith .  snes - the SNES context
2868e35cf81dSBarry Smith 
2869e35cf81dSBarry Smith    Output Parameter:
2870e35cf81dSBarry 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
2871e35cf81dSBarry Smith          the Jacobian is built etc.
2872e35cf81dSBarry Smith 
2873e35cf81dSBarry Smith    Options Database Keys:
2874e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2875e35cf81dSBarry Smith 
2876e35cf81dSBarry Smith    Notes:
2877e35cf81dSBarry Smith    The default is 1
2878e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2879e35cf81dSBarry Smith 
2880e35cf81dSBarry Smith    Level: intermediate
2881e35cf81dSBarry Smith 
2882e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2883e35cf81dSBarry Smith 
2884e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2885e35cf81dSBarry Smith 
2886e35cf81dSBarry Smith @*/
28877087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2888e35cf81dSBarry Smith {
2889e35cf81dSBarry Smith   PetscFunctionBegin;
28900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2891e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2892e35cf81dSBarry Smith   PetscFunctionReturn(0);
2893e35cf81dSBarry Smith }
2894e35cf81dSBarry Smith 
2895e35cf81dSBarry Smith #undef __FUNCT__
28964a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
28979b94acceSBarry Smith /*@
2898d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
28999b94acceSBarry Smith 
29003f9fe445SBarry Smith    Logically Collective on SNES
2901c7afd0dbSLois Curfman McInnes 
29029b94acceSBarry Smith    Input Parameters:
2903c7afd0dbSLois Curfman McInnes +  snes - the SNES context
290470441072SBarry Smith .  abstol - absolute convergence tolerance
290533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
29065358d0d4SBarry Smith .  stol -  convergence tolerance in terms of the norm of the change in the solution between steps,  || delta x || < stol*|| x ||
290733174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2908c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2909fee21e36SBarry Smith 
291033174efeSLois Curfman McInnes    Options Database Keys:
291170441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2912c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2913c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2914c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2915c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
29169b94acceSBarry Smith 
2917d7a720efSLois Curfman McInnes    Notes:
29189b94acceSBarry Smith    The default maximum number of iterations is 50.
29199b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
29209b94acceSBarry Smith 
292136851e7fSLois Curfman McInnes    Level: intermediate
292236851e7fSLois Curfman McInnes 
292333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
29249b94acceSBarry Smith 
29252492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
29269b94acceSBarry Smith @*/
29277087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
29289b94acceSBarry Smith {
29293a40ed3dSBarry Smith   PetscFunctionBegin;
29300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2931c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2932c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2933c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2934c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2935c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2936c5eb9154SBarry Smith 
2937ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2938ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2939ab54825eSJed Brown     snes->abstol = abstol;
2940ab54825eSJed Brown   }
2941ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2942ab54825eSJed Brown     if (rtol < 0.0 || 1.0 <= rtol) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %G must be non-negative and less than 1.0",rtol);
2943ab54825eSJed Brown     snes->rtol = rtol;
2944ab54825eSJed Brown   }
2945ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2946ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2947c60f73f4SPeter Brune     snes->stol = stol;
2948ab54825eSJed Brown   }
2949ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2950ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2951ab54825eSJed Brown     snes->max_its = maxit;
2952ab54825eSJed Brown   }
2953ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2954ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2955ab54825eSJed Brown     snes->max_funcs = maxf;
2956ab54825eSJed Brown   }
295788976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
29583a40ed3dSBarry Smith   PetscFunctionReturn(0);
29599b94acceSBarry Smith }
29609b94acceSBarry Smith 
29614a2ae208SSatish Balay #undef __FUNCT__
29624a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
29639b94acceSBarry Smith /*@
296433174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
296533174efeSLois Curfman McInnes 
2966c7afd0dbSLois Curfman McInnes    Not Collective
2967c7afd0dbSLois Curfman McInnes 
296833174efeSLois Curfman McInnes    Input Parameters:
2969c7afd0dbSLois Curfman McInnes +  snes - the SNES context
297085385478SLisandro Dalcin .  atol - absolute convergence tolerance
297133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
297233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
297333174efeSLois Curfman McInnes            of the change in the solution between steps
297433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2975c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2976fee21e36SBarry Smith 
297733174efeSLois Curfman McInnes    Notes:
297833174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
297933174efeSLois Curfman McInnes 
298036851e7fSLois Curfman McInnes    Level: intermediate
298136851e7fSLois Curfman McInnes 
298233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
298333174efeSLois Curfman McInnes 
298433174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
298533174efeSLois Curfman McInnes @*/
29867087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
298733174efeSLois Curfman McInnes {
29883a40ed3dSBarry Smith   PetscFunctionBegin;
29890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
299085385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
299133174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2992c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
299333174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
299433174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
29953a40ed3dSBarry Smith   PetscFunctionReturn(0);
299633174efeSLois Curfman McInnes }
299733174efeSLois Curfman McInnes 
29984a2ae208SSatish Balay #undef __FUNCT__
29994a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
300033174efeSLois Curfman McInnes /*@
30019b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
30029b94acceSBarry Smith 
30033f9fe445SBarry Smith    Logically Collective on SNES
3004fee21e36SBarry Smith 
3005c7afd0dbSLois Curfman McInnes    Input Parameters:
3006c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3007c7afd0dbSLois Curfman McInnes -  tol - tolerance
3008c7afd0dbSLois Curfman McInnes 
30099b94acceSBarry Smith    Options Database Key:
3010c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
30119b94acceSBarry Smith 
301236851e7fSLois Curfman McInnes    Level: intermediate
301336851e7fSLois Curfman McInnes 
30149b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
30159b94acceSBarry Smith 
30162492ecdbSBarry Smith .seealso: SNESSetTolerances()
30179b94acceSBarry Smith @*/
30187087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
30199b94acceSBarry Smith {
30203a40ed3dSBarry Smith   PetscFunctionBegin;
30210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3022c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
30239b94acceSBarry Smith   snes->deltatol = tol;
30243a40ed3dSBarry Smith   PetscFunctionReturn(0);
30259b94acceSBarry Smith }
30269b94acceSBarry Smith 
3027df9fa365SBarry Smith /*
3028df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
3029df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
3030df9fa365SBarry Smith    macros instead of functions
3031df9fa365SBarry Smith */
30324a2ae208SSatish Balay #undef __FUNCT__
30334619e776SBarry Smith #define __FUNCT__ "SNESMonitorLGResidualNorm"
30344619e776SBarry Smith PetscErrorCode  SNESMonitorLGResidualNorm(SNES snes,PetscInt it,PetscReal norm,void *ctx)
3035ce1608b8SBarry Smith {
3036dfbe8321SBarry Smith   PetscErrorCode ierr;
3037ce1608b8SBarry Smith 
3038ce1608b8SBarry Smith   PetscFunctionBegin;
30390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30401d1e9da1SBarry Smith   ierr = KSPMonitorLGResidualNorm((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
3041ce1608b8SBarry Smith   PetscFunctionReturn(0);
3042ce1608b8SBarry Smith }
3043ce1608b8SBarry Smith 
30444a2ae208SSatish Balay #undef __FUNCT__
3045a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
30467087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
3047df9fa365SBarry Smith {
3048dfbe8321SBarry Smith   PetscErrorCode ierr;
3049df9fa365SBarry Smith 
3050df9fa365SBarry Smith   PetscFunctionBegin;
30511d1e9da1SBarry Smith   ierr = KSPMonitorLGResidualNormCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
3052df9fa365SBarry Smith   PetscFunctionReturn(0);
3053df9fa365SBarry Smith }
3054df9fa365SBarry Smith 
30554a2ae208SSatish Balay #undef __FUNCT__
3056a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
30576bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
3058df9fa365SBarry Smith {
3059dfbe8321SBarry Smith   PetscErrorCode ierr;
3060df9fa365SBarry Smith 
3061df9fa365SBarry Smith   PetscFunctionBegin;
30621d1e9da1SBarry Smith   ierr = KSPMonitorLGResidualNormDestroy(draw);CHKERRQ(ierr);
3063df9fa365SBarry Smith   PetscFunctionReturn(0);
3064df9fa365SBarry Smith }
3065df9fa365SBarry Smith 
30667087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
3067b271bb04SBarry Smith #undef __FUNCT__
3068b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
30697087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
3070b271bb04SBarry Smith {
3071b271bb04SBarry Smith   PetscDrawLG      lg;
3072b271bb04SBarry Smith   PetscErrorCode   ierr;
3073b271bb04SBarry Smith   PetscReal        x,y,per;
3074b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
3075b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
3076b271bb04SBarry Smith   PetscDraw        draw;
3077b271bb04SBarry Smith 
3078459f5d12SBarry Smith   PetscFunctionBegin;
3079b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
3080b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3081b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3082b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
3083b271bb04SBarry Smith   x = (PetscReal) n;
3084b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
3085b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3086b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3087b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3088b271bb04SBarry Smith   }
3089b271bb04SBarry Smith 
3090b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
3091b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3092b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3093b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
3094b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
3095b271bb04SBarry Smith   x = (PetscReal) n;
3096b271bb04SBarry Smith   y = 100.0*per;
3097b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3098b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3099b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3100b271bb04SBarry Smith   }
3101b271bb04SBarry Smith 
3102b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
3103b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3104b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3105b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
3106b271bb04SBarry Smith   x = (PetscReal) n;
3107b271bb04SBarry Smith   y = (prev - rnorm)/prev;
3108b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3109b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3110b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3111b271bb04SBarry Smith   }
3112b271bb04SBarry Smith 
3113b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
3114b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
3115b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
3116b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
3117b271bb04SBarry Smith   x = (PetscReal) n;
3118b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
3119b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
3120b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
3121b271bb04SBarry Smith   }
3122b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
3123b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
3124b271bb04SBarry Smith   }
3125b271bb04SBarry Smith   prev = rnorm;
3126b271bb04SBarry Smith   PetscFunctionReturn(0);
3127b271bb04SBarry Smith }
3128b271bb04SBarry Smith 
3129b271bb04SBarry Smith #undef __FUNCT__
31307a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
3131228d79bcSJed Brown /*@
3132228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
3133228d79bcSJed Brown 
3134228d79bcSJed Brown    Collective on SNES
3135228d79bcSJed Brown 
3136228d79bcSJed Brown    Input Parameters:
3137228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
3138228d79bcSJed Brown .  iter - iteration number
3139228d79bcSJed Brown -  rnorm - relative norm of the residual
3140228d79bcSJed Brown 
3141228d79bcSJed Brown    Notes:
3142228d79bcSJed Brown    This routine is called by the SNES implementations.
3143228d79bcSJed Brown    It does not typically need to be called by the user.
3144228d79bcSJed Brown 
3145228d79bcSJed Brown    Level: developer
3146228d79bcSJed Brown 
3147228d79bcSJed Brown .seealso: SNESMonitorSet()
3148228d79bcSJed Brown @*/
31497a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
31507a03ce2fSLisandro Dalcin {
31517a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
31527a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
31537a03ce2fSLisandro Dalcin 
31547a03ce2fSLisandro Dalcin   PetscFunctionBegin;
31557a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
31567a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
31577a03ce2fSLisandro Dalcin   }
31587a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
31597a03ce2fSLisandro Dalcin }
31607a03ce2fSLisandro Dalcin 
31619b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
31629b94acceSBarry Smith 
31634a2ae208SSatish Balay #undef __FUNCT__
3164a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
31659b94acceSBarry Smith /*@C
3166a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
31679b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
31689b94acceSBarry Smith    progress.
31699b94acceSBarry Smith 
31703f9fe445SBarry Smith    Logically Collective on SNES
3171fee21e36SBarry Smith 
3172c7afd0dbSLois Curfman McInnes    Input Parameters:
3173c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3174c7afd0dbSLois Curfman McInnes .  func - monitoring routine
3175b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
3176e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
3177b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
3178b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
31799b94acceSBarry Smith 
3180c7afd0dbSLois Curfman McInnes    Calling sequence of func:
3181a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
3182c7afd0dbSLois Curfman McInnes 
3183c7afd0dbSLois Curfman McInnes +    snes - the SNES context
3184c7afd0dbSLois Curfman McInnes .    its - iteration number
3185c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
318640a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
31879b94acceSBarry Smith 
31889665c990SLois Curfman McInnes    Options Database Keys:
3189a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
31904619e776SBarry Smith .    -snes_monitor_lg_residualnorm    - sets line graph monitor,
3191a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
3192cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
3193c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
3194a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
3195c7afd0dbSLois Curfman McInnes                             does not cancel those set via
3196c7afd0dbSLois Curfman McInnes                             the options database.
31979665c990SLois Curfman McInnes 
3198639f9d9dSBarry Smith    Notes:
31996bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
3200a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
32016bc08f3fSLois Curfman McInnes    order in which they were set.
3202639f9d9dSBarry Smith 
3203025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
3204025f1a04SBarry Smith 
320536851e7fSLois Curfman McInnes    Level: intermediate
320636851e7fSLois Curfman McInnes 
32079b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
32089b94acceSBarry Smith 
3209a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
32109b94acceSBarry Smith @*/
3211c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
32129b94acceSBarry Smith {
3213b90d0a6eSBarry Smith   PetscInt       i;
3214649052a6SBarry Smith   PetscErrorCode ierr;
3215b90d0a6eSBarry Smith 
32163a40ed3dSBarry Smith   PetscFunctionBegin;
32170700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
321817186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3219b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3220649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3221649052a6SBarry Smith       if (monitordestroy) {
3222c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3223649052a6SBarry Smith       }
3224b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3225b90d0a6eSBarry Smith     }
3226b90d0a6eSBarry Smith   }
3227b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3228b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3229639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
32303a40ed3dSBarry Smith   PetscFunctionReturn(0);
32319b94acceSBarry Smith }
32329b94acceSBarry Smith 
32334a2ae208SSatish Balay #undef __FUNCT__
3234a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
32355cd90555SBarry Smith /*@C
3236a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
32375cd90555SBarry Smith 
32383f9fe445SBarry Smith    Logically Collective on SNES
3239c7afd0dbSLois Curfman McInnes 
32405cd90555SBarry Smith    Input Parameters:
32415cd90555SBarry Smith .  snes - the SNES context
32425cd90555SBarry Smith 
32431a480d89SAdministrator    Options Database Key:
3244a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3245a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3246c7afd0dbSLois Curfman McInnes     set via the options database
32475cd90555SBarry Smith 
32485cd90555SBarry Smith    Notes:
32495cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
32505cd90555SBarry Smith 
325136851e7fSLois Curfman McInnes    Level: intermediate
325236851e7fSLois Curfman McInnes 
32535cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
32545cd90555SBarry Smith 
3255a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
32565cd90555SBarry Smith @*/
32577087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
32585cd90555SBarry Smith {
3259d952e501SBarry Smith   PetscErrorCode ierr;
3260d952e501SBarry Smith   PetscInt       i;
3261d952e501SBarry Smith 
32625cd90555SBarry Smith   PetscFunctionBegin;
32630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3264d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3265d952e501SBarry Smith     if (snes->monitordestroy[i]) {
32663c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3267d952e501SBarry Smith     }
3268d952e501SBarry Smith   }
32695cd90555SBarry Smith   snes->numbermonitors = 0;
32705cd90555SBarry Smith   PetscFunctionReturn(0);
32715cd90555SBarry Smith }
32725cd90555SBarry Smith 
32734a2ae208SSatish Balay #undef __FUNCT__
32744a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
32759b94acceSBarry Smith /*@C
32769b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
32779b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
32789b94acceSBarry Smith 
32793f9fe445SBarry Smith    Logically Collective on SNES
3280fee21e36SBarry Smith 
3281c7afd0dbSLois Curfman McInnes    Input Parameters:
3282c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3283c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
32847f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
32857f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
32869b94acceSBarry Smith 
3287c7afd0dbSLois Curfman McInnes    Calling sequence of func:
328806ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3289c7afd0dbSLois Curfman McInnes 
3290c7afd0dbSLois Curfman McInnes +    snes - the SNES context
329106ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3292c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3293184914b5SBarry Smith .    reason - reason for convergence/divergence
3294c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
32954b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
32964b27c08aSLois Curfman McInnes -    f - 2-norm of function
32979b94acceSBarry Smith 
329836851e7fSLois Curfman McInnes    Level: advanced
329936851e7fSLois Curfman McInnes 
33009b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
33019b94acceSBarry Smith 
330285385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
33039b94acceSBarry Smith @*/
33047087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
33059b94acceSBarry Smith {
33067f7931b9SBarry Smith   PetscErrorCode ierr;
33077f7931b9SBarry Smith 
33083a40ed3dSBarry Smith   PetscFunctionBegin;
33090700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
331085385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
33117f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
33127f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
33137f7931b9SBarry Smith   }
331485385478SLisandro Dalcin   snes->ops->converged        = func;
33157f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
331685385478SLisandro Dalcin   snes->cnvP                  = cctx;
33173a40ed3dSBarry Smith   PetscFunctionReturn(0);
33189b94acceSBarry Smith }
33199b94acceSBarry Smith 
33204a2ae208SSatish Balay #undef __FUNCT__
33214a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
332252baeb72SSatish Balay /*@
3323184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3324184914b5SBarry Smith 
3325184914b5SBarry Smith    Not Collective
3326184914b5SBarry Smith 
3327184914b5SBarry Smith    Input Parameter:
3328184914b5SBarry Smith .  snes - the SNES context
3329184914b5SBarry Smith 
3330184914b5SBarry Smith    Output Parameter:
33314d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3332184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3333184914b5SBarry Smith 
3334184914b5SBarry Smith    Level: intermediate
3335184914b5SBarry Smith 
3336184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3337184914b5SBarry Smith 
3338184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3339184914b5SBarry Smith 
334085385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3341184914b5SBarry Smith @*/
33427087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3343184914b5SBarry Smith {
3344184914b5SBarry Smith   PetscFunctionBegin;
33450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33464482741eSBarry Smith   PetscValidPointer(reason,2);
3347184914b5SBarry Smith   *reason = snes->reason;
3348184914b5SBarry Smith   PetscFunctionReturn(0);
3349184914b5SBarry Smith }
3350184914b5SBarry Smith 
33514a2ae208SSatish Balay #undef __FUNCT__
33524a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3353c9005455SLois Curfman McInnes /*@
3354c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3355c9005455SLois Curfman McInnes 
33563f9fe445SBarry Smith    Logically Collective on SNES
3357fee21e36SBarry Smith 
3358c7afd0dbSLois Curfman McInnes    Input Parameters:
3359c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
33608c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3361cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3362758f92a0SBarry Smith .  na  - size of a and its
336364731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3364758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3365c7afd0dbSLois Curfman McInnes 
3366308dcc3eSBarry Smith    Notes:
3367308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3368308dcc3eSBarry Smith    default array of length 10000 is allocated.
3369308dcc3eSBarry Smith 
3370c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3371c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3372c9005455SLois Curfman McInnes    during the section of code that is being timed.
3373c9005455SLois Curfman McInnes 
337436851e7fSLois Curfman McInnes    Level: intermediate
337536851e7fSLois Curfman McInnes 
3376c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3377758f92a0SBarry Smith 
337808405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3379758f92a0SBarry Smith 
3380c9005455SLois Curfman McInnes @*/
33817087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3382c9005455SLois Curfman McInnes {
3383308dcc3eSBarry Smith   PetscErrorCode ierr;
3384308dcc3eSBarry Smith 
33853a40ed3dSBarry Smith   PetscFunctionBegin;
33860700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33874482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3388a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3389308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3390308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3391308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3392308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3393308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3394308dcc3eSBarry Smith   }
3395c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3396758f92a0SBarry Smith   snes->conv_hist_its   = its;
3397758f92a0SBarry Smith   snes->conv_hist_max   = na;
3398a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3399758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3400758f92a0SBarry Smith   PetscFunctionReturn(0);
3401758f92a0SBarry Smith }
3402758f92a0SBarry Smith 
3403308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3404c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3405c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3406308dcc3eSBarry Smith EXTERN_C_BEGIN
3407308dcc3eSBarry Smith #undef __FUNCT__
3408308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3409308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3410308dcc3eSBarry Smith {
3411308dcc3eSBarry Smith   mxArray   *mat;
3412308dcc3eSBarry Smith   PetscInt  i;
3413308dcc3eSBarry Smith   PetscReal *ar;
3414308dcc3eSBarry Smith 
3415308dcc3eSBarry Smith   PetscFunctionBegin;
3416308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3417308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3418308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3419308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3420308dcc3eSBarry Smith   }
3421308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3422308dcc3eSBarry Smith }
3423308dcc3eSBarry Smith EXTERN_C_END
3424308dcc3eSBarry Smith #endif
3425308dcc3eSBarry Smith 
3426308dcc3eSBarry Smith 
34274a2ae208SSatish Balay #undef __FUNCT__
34284a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
34290c4c9dddSBarry Smith /*@C
3430758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3431758f92a0SBarry Smith 
34323f9fe445SBarry Smith    Not Collective
3433758f92a0SBarry Smith 
3434758f92a0SBarry Smith    Input Parameter:
3435758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3436758f92a0SBarry Smith 
3437758f92a0SBarry Smith    Output Parameters:
3438758f92a0SBarry Smith .  a   - array to hold history
3439758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3440758f92a0SBarry Smith          negative if not converged) for each solve.
3441758f92a0SBarry Smith -  na  - size of a and its
3442758f92a0SBarry Smith 
3443758f92a0SBarry Smith    Notes:
3444758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3445758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3446758f92a0SBarry Smith 
3447758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3448758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3449758f92a0SBarry Smith    during the section of code that is being timed.
3450758f92a0SBarry Smith 
3451758f92a0SBarry Smith    Level: intermediate
3452758f92a0SBarry Smith 
3453758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3454758f92a0SBarry Smith 
3455758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3456758f92a0SBarry Smith 
3457758f92a0SBarry Smith @*/
34587087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3459758f92a0SBarry Smith {
3460758f92a0SBarry Smith   PetscFunctionBegin;
34610700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3462758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3463758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3464758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
34653a40ed3dSBarry Smith   PetscFunctionReturn(0);
3466c9005455SLois Curfman McInnes }
3467c9005455SLois Curfman McInnes 
3468e74ef692SMatthew Knepley #undef __FUNCT__
3469e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3470ac226902SBarry Smith /*@C
347176b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3472eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
34737e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
347476b2cf59SMatthew Knepley 
34753f9fe445SBarry Smith   Logically Collective on SNES
347676b2cf59SMatthew Knepley 
347776b2cf59SMatthew Knepley   Input Parameters:
347876b2cf59SMatthew Knepley . snes - The nonlinear solver context
347976b2cf59SMatthew Knepley . func - The function
348076b2cf59SMatthew Knepley 
348176b2cf59SMatthew Knepley   Calling sequence of func:
3482b5d30489SBarry Smith . func (SNES snes, PetscInt step);
348376b2cf59SMatthew Knepley 
348476b2cf59SMatthew Knepley . step - The current step of the iteration
348576b2cf59SMatthew Knepley 
3486fe97e370SBarry Smith   Level: advanced
3487fe97e370SBarry Smith 
3488fe97e370SBarry 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()
3489fe97e370SBarry Smith         This is not used by most users.
349076b2cf59SMatthew Knepley 
349176b2cf59SMatthew Knepley .keywords: SNES, update
3492b5d30489SBarry Smith 
349385385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
349476b2cf59SMatthew Knepley @*/
34957087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
349676b2cf59SMatthew Knepley {
349776b2cf59SMatthew Knepley   PetscFunctionBegin;
34980700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3499e7788613SBarry Smith   snes->ops->update = func;
350076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
350176b2cf59SMatthew Knepley }
350276b2cf59SMatthew Knepley 
3503e74ef692SMatthew Knepley #undef __FUNCT__
3504e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
350576b2cf59SMatthew Knepley /*@
350676b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
350776b2cf59SMatthew Knepley 
350876b2cf59SMatthew Knepley   Not collective
350976b2cf59SMatthew Knepley 
351076b2cf59SMatthew Knepley   Input Parameters:
351176b2cf59SMatthew Knepley . snes - The nonlinear solver context
351276b2cf59SMatthew Knepley . step - The current step of the iteration
351376b2cf59SMatthew Knepley 
3514205452f4SMatthew Knepley   Level: intermediate
3515205452f4SMatthew Knepley 
351676b2cf59SMatthew Knepley .keywords: SNES, update
3517a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
351876b2cf59SMatthew Knepley @*/
35197087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
352076b2cf59SMatthew Knepley {
352176b2cf59SMatthew Knepley   PetscFunctionBegin;
352276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
352376b2cf59SMatthew Knepley }
352476b2cf59SMatthew Knepley 
35254a2ae208SSatish Balay #undef __FUNCT__
35264a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
35279b94acceSBarry Smith /*
35289b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
35299b94acceSBarry Smith    positive parameter delta.
35309b94acceSBarry Smith 
35319b94acceSBarry Smith     Input Parameters:
3532c7afd0dbSLois Curfman McInnes +   snes - the SNES context
35339b94acceSBarry Smith .   y - approximate solution of linear system
35349b94acceSBarry Smith .   fnorm - 2-norm of current function
3535c7afd0dbSLois Curfman McInnes -   delta - trust region size
35369b94acceSBarry Smith 
35379b94acceSBarry Smith     Output Parameters:
3538c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
35399b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
35409b94acceSBarry Smith     region, and exceeds zero otherwise.
3541c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
35429b94acceSBarry Smith 
35439b94acceSBarry Smith     Note:
35444b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
35459b94acceSBarry Smith     is set to be the maximum allowable step size.
35469b94acceSBarry Smith 
35479b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
35489b94acceSBarry Smith */
3549dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
35509b94acceSBarry Smith {
3551064f8208SBarry Smith   PetscReal      nrm;
3552ea709b57SSatish Balay   PetscScalar    cnorm;
3553dfbe8321SBarry Smith   PetscErrorCode ierr;
35543a40ed3dSBarry Smith 
35553a40ed3dSBarry Smith   PetscFunctionBegin;
35560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35570700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3558c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3559184914b5SBarry Smith 
3560064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3561064f8208SBarry Smith   if (nrm > *delta) {
3562064f8208SBarry Smith      nrm = *delta/nrm;
3563064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3564064f8208SBarry Smith      cnorm = nrm;
35652dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
35669b94acceSBarry Smith      *ynorm = *delta;
35679b94acceSBarry Smith   } else {
35689b94acceSBarry Smith      *gpnorm = 0.0;
3569064f8208SBarry Smith      *ynorm = nrm;
35709b94acceSBarry Smith   }
35713a40ed3dSBarry Smith   PetscFunctionReturn(0);
35729b94acceSBarry Smith }
35739b94acceSBarry Smith 
35744a2ae208SSatish Balay #undef __FUNCT__
35754a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
35766ce558aeSBarry Smith /*@C
3577f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3578f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
35799b94acceSBarry Smith 
3580c7afd0dbSLois Curfman McInnes    Collective on SNES
3581c7afd0dbSLois Curfman McInnes 
3582b2002411SLois Curfman McInnes    Input Parameters:
3583c7afd0dbSLois Curfman McInnes +  snes - the SNES context
35843cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
358585385478SLisandro Dalcin -  x - the solution vector.
35869b94acceSBarry Smith 
3587b2002411SLois Curfman McInnes    Notes:
35888ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
35898ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
35908ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
35918ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
35928ddd3da0SLois Curfman McInnes 
359336851e7fSLois Curfman McInnes    Level: beginner
359436851e7fSLois Curfman McInnes 
35959b94acceSBarry Smith .keywords: SNES, nonlinear, solve
35969b94acceSBarry Smith 
3597c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
35989b94acceSBarry Smith @*/
35997087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
36009b94acceSBarry Smith {
3601dfbe8321SBarry Smith   PetscErrorCode ierr;
3602ace3abfcSBarry Smith   PetscBool      flg;
3603eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3604eabae89aSBarry Smith   PetscViewer    viewer;
3605efd51863SBarry Smith   PetscInt       grid;
3606a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3607caa4e7f2SJed Brown   DM             dm;
3608052efed2SBarry Smith 
36093a40ed3dSBarry Smith   PetscFunctionBegin;
36100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3611a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3612a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
36130700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
361485385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
361585385478SLisandro Dalcin 
3616caa4e7f2SJed Brown   if (!x) {
3617caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3618caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3619a69afd8bSBarry Smith     x    = xcreated;
3620a69afd8bSBarry Smith   }
3621a69afd8bSBarry Smith 
3622a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3623efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3624efd51863SBarry Smith 
362585385478SLisandro Dalcin     /* set solution vector */
3626efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
36276bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
362885385478SLisandro Dalcin     snes->vec_sol = x;
3629caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3630caa4e7f2SJed Brown 
3631caa4e7f2SJed Brown     /* set affine vector if provided */
363285385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
36336bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
363485385478SLisandro Dalcin     snes->vec_rhs = b;
363585385478SLisandro Dalcin 
363670e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
36373f149594SLisandro Dalcin 
36387eee914bSBarry Smith     if (!grid) {
36397eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3640d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3641d25893d9SBarry Smith       }
3642dd568438SSatish Balay     }
3643d25893d9SBarry Smith 
3644abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
364550ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3646d5e45103SBarry Smith 
36473f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
36484936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
364985385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
36504936397dSBarry Smith     if (snes->domainerror){
36514936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
36524936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
36534936397dSBarry Smith     }
365417186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
36553f149594SLisandro Dalcin 
365690d69ab7SBarry Smith     flg  = PETSC_FALSE;
3657acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3658da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
36595968eb51SBarry Smith     if (snes->printreason) {
3660a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
36615968eb51SBarry Smith       if (snes->reason > 0) {
3662c7e7b494SJed Brown         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
36635968eb51SBarry Smith       } else {
3664c7e7b494SJed Brown         ierr = PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s iterations %D\n",SNESConvergedReasons[snes->reason],snes->iter);CHKERRQ(ierr);
36655968eb51SBarry Smith       }
3666a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
36675968eb51SBarry Smith     }
36685968eb51SBarry Smith 
3669e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3670efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3671efd51863SBarry Smith       DM  fine;
3672efd51863SBarry Smith       Vec xnew;
3673efd51863SBarry Smith       Mat interp;
3674efd51863SBarry Smith 
3675efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3676c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3677e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3678efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3679efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3680c833c3b5SJed Brown       ierr = DMInterpolate(snes->dm,interp,fine);CHKERRQ(ierr);
3681efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3682efd51863SBarry Smith       x    = xnew;
3683efd51863SBarry Smith 
3684efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3685efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3686efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3687a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3688efd51863SBarry Smith     }
3689efd51863SBarry Smith   }
36903f7e2da0SPeter Brune   /* monitoring and viewing */
36913f7e2da0SPeter Brune   flg = PETSC_FALSE;
36923f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
36933f7e2da0SPeter Brune   if (flg && !PetscPreLoadingOn) {
36943f7e2da0SPeter Brune     ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
36953f7e2da0SPeter Brune     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
36963f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
36973f7e2da0SPeter Brune   }
36983f7e2da0SPeter Brune 
36993f7e2da0SPeter Brune   flg = PETSC_FALSE;
370072a02f06SBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_view_draw",&flg,PETSC_NULL);CHKERRQ(ierr);
370172a02f06SBarry Smith   if (flg) {
370272a02f06SBarry Smith     ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,PETSC_NULL,"SNES Solver",0,0,600,600,&viewer);CHKERRQ(ierr);
370372a02f06SBarry Smith     ierr = SNESView(snes,viewer);CHKERRQ(ierr);
370472a02f06SBarry Smith     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
370572a02f06SBarry Smith   }
370672a02f06SBarry Smith 
370772a02f06SBarry Smith   flg = PETSC_FALSE;
37083f7e2da0SPeter Brune   ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
37093f7e2da0SPeter Brune   if (flg) {
37103f7e2da0SPeter Brune     PetscViewer viewer;
37113f7e2da0SPeter Brune     ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
37123f7e2da0SPeter Brune     ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
37133f7e2da0SPeter Brune     ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
37143f7e2da0SPeter Brune     ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
37153f7e2da0SPeter Brune     ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
37163f7e2da0SPeter Brune   }
37173f7e2da0SPeter Brune 
3718a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
37193a40ed3dSBarry Smith   PetscFunctionReturn(0);
37209b94acceSBarry Smith }
37219b94acceSBarry Smith 
37229b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
37239b94acceSBarry Smith 
37244a2ae208SSatish Balay #undef __FUNCT__
37254a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
372682bf6240SBarry Smith /*@C
37274b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
37289b94acceSBarry Smith 
3729fee21e36SBarry Smith    Collective on SNES
3730fee21e36SBarry Smith 
3731c7afd0dbSLois Curfman McInnes    Input Parameters:
3732c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3733454a90a3SBarry Smith -  type - a known method
3734c7afd0dbSLois Curfman McInnes 
3735c7afd0dbSLois Curfman McInnes    Options Database Key:
3736454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3737c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3738ae12b187SLois Curfman McInnes 
37399b94acceSBarry Smith    Notes:
3740e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
37414b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3742c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
37434b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3744c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
37459b94acceSBarry Smith 
3746ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3747ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3748ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3749ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3750ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3751ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3752ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3753ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3754ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3755b0a32e0cSBarry Smith   appropriate method.
375636851e7fSLois Curfman McInnes 
375736851e7fSLois Curfman McInnes   Level: intermediate
3758a703fe33SLois Curfman McInnes 
3759454a90a3SBarry Smith .keywords: SNES, set, type
3760435da068SBarry Smith 
3761435da068SBarry Smith .seealso: SNESType, SNESCreate()
3762435da068SBarry Smith 
37639b94acceSBarry Smith @*/
376419fd82e9SBarry Smith PetscErrorCode  SNESSetType(SNES snes,SNESType type)
37659b94acceSBarry Smith {
3766dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3767ace3abfcSBarry Smith   PetscBool      match;
37683a40ed3dSBarry Smith 
37693a40ed3dSBarry Smith   PetscFunctionBegin;
37700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37714482741eSBarry Smith   PetscValidCharPointer(type,2);
377282bf6240SBarry Smith 
3773251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
37740f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
377592ff6ae8SBarry Smith 
37764b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3777e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
377875396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3779b5c23020SJed Brown   if (snes->ops->destroy) {
3780b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3781b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3782b5c23020SJed Brown   }
378375396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
378475396ef9SLisandro Dalcin   snes->ops->setup          = 0;
378575396ef9SLisandro Dalcin   snes->ops->solve          = 0;
378675396ef9SLisandro Dalcin   snes->ops->view           = 0;
378775396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
378875396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
378975396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
379075396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3791454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
379203bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
37939fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
37949fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
37959fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
37969fb22e1aSBarry Smith   }
37979fb22e1aSBarry Smith #endif
37983a40ed3dSBarry Smith   PetscFunctionReturn(0);
37999b94acceSBarry Smith }
38009b94acceSBarry Smith 
3801a847f771SSatish Balay 
38029b94acceSBarry Smith /* --------------------------------------------------------------------- */
38034a2ae208SSatish Balay #undef __FUNCT__
38044a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
380552baeb72SSatish Balay /*@
38069b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3807f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
38089b94acceSBarry Smith 
3809fee21e36SBarry Smith    Not Collective
3810fee21e36SBarry Smith 
381136851e7fSLois Curfman McInnes    Level: advanced
381236851e7fSLois Curfman McInnes 
38139b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
38149b94acceSBarry Smith 
38159b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
38169b94acceSBarry Smith @*/
38177087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
38189b94acceSBarry Smith {
3819dfbe8321SBarry Smith   PetscErrorCode ierr;
382082bf6240SBarry Smith 
38213a40ed3dSBarry Smith   PetscFunctionBegin;
38221441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
38234c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
38243a40ed3dSBarry Smith   PetscFunctionReturn(0);
38259b94acceSBarry Smith }
38269b94acceSBarry Smith 
38274a2ae208SSatish Balay #undef __FUNCT__
38284a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
38299b94acceSBarry Smith /*@C
38309a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
38319b94acceSBarry Smith 
3832c7afd0dbSLois Curfman McInnes    Not Collective
3833c7afd0dbSLois Curfman McInnes 
38349b94acceSBarry Smith    Input Parameter:
38354b0e389bSBarry Smith .  snes - nonlinear solver context
38369b94acceSBarry Smith 
38379b94acceSBarry Smith    Output Parameter:
38383a7fca6bSBarry Smith .  type - SNES method (a character string)
38399b94acceSBarry Smith 
384036851e7fSLois Curfman McInnes    Level: intermediate
384136851e7fSLois Curfman McInnes 
3842454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
38439b94acceSBarry Smith @*/
384419fd82e9SBarry Smith PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
38459b94acceSBarry Smith {
38463a40ed3dSBarry Smith   PetscFunctionBegin;
38470700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38484482741eSBarry Smith   PetscValidPointer(type,2);
38497adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
38503a40ed3dSBarry Smith   PetscFunctionReturn(0);
38519b94acceSBarry Smith }
38529b94acceSBarry Smith 
38534a2ae208SSatish Balay #undef __FUNCT__
38544a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
385552baeb72SSatish Balay /*@
38569b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3857c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
38589b94acceSBarry Smith 
3859c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3860c7afd0dbSLois Curfman McInnes 
38619b94acceSBarry Smith    Input Parameter:
38629b94acceSBarry Smith .  snes - the SNES context
38639b94acceSBarry Smith 
38649b94acceSBarry Smith    Output Parameter:
38659b94acceSBarry Smith .  x - the solution
38669b94acceSBarry Smith 
386770e92668SMatthew Knepley    Level: intermediate
386836851e7fSLois Curfman McInnes 
38699b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
38709b94acceSBarry Smith 
387185385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
38729b94acceSBarry Smith @*/
38737087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
38749b94acceSBarry Smith {
38753a40ed3dSBarry Smith   PetscFunctionBegin;
38760700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
38774482741eSBarry Smith   PetscValidPointer(x,2);
387885385478SLisandro Dalcin   *x = snes->vec_sol;
387970e92668SMatthew Knepley   PetscFunctionReturn(0);
388070e92668SMatthew Knepley }
388170e92668SMatthew Knepley 
388270e92668SMatthew Knepley #undef __FUNCT__
38834a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
388452baeb72SSatish Balay /*@
38859b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
38869b94acceSBarry Smith    stored.
38879b94acceSBarry Smith 
3888c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3889c7afd0dbSLois Curfman McInnes 
38909b94acceSBarry Smith    Input Parameter:
38919b94acceSBarry Smith .  snes - the SNES context
38929b94acceSBarry Smith 
38939b94acceSBarry Smith    Output Parameter:
38949b94acceSBarry Smith .  x - the solution update
38959b94acceSBarry Smith 
389636851e7fSLois Curfman McInnes    Level: advanced
389736851e7fSLois Curfman McInnes 
38989b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
38999b94acceSBarry Smith 
390085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
39019b94acceSBarry Smith @*/
39027087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
39039b94acceSBarry Smith {
39043a40ed3dSBarry Smith   PetscFunctionBegin;
39050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39064482741eSBarry Smith   PetscValidPointer(x,2);
390785385478SLisandro Dalcin   *x = snes->vec_sol_update;
39083a40ed3dSBarry Smith   PetscFunctionReturn(0);
39099b94acceSBarry Smith }
39109b94acceSBarry Smith 
39114a2ae208SSatish Balay #undef __FUNCT__
39124a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
39139b94acceSBarry Smith /*@C
39143638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
39159b94acceSBarry Smith 
3916a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3917c7afd0dbSLois Curfman McInnes 
39189b94acceSBarry Smith    Input Parameter:
39199b94acceSBarry Smith .  snes - the SNES context
39209b94acceSBarry Smith 
39219b94acceSBarry Smith    Output Parameter:
39227bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
392370e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
392470e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
39259b94acceSBarry Smith 
392636851e7fSLois Curfman McInnes    Level: advanced
392736851e7fSLois Curfman McInnes 
3928a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
39299b94acceSBarry Smith 
39304b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
39319b94acceSBarry Smith @*/
39327087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
39339b94acceSBarry Smith {
3934a63bb30eSJed Brown   PetscErrorCode ierr;
39356cab3a1bSJed Brown   DM             dm;
3936a63bb30eSJed Brown 
39373a40ed3dSBarry Smith   PetscFunctionBegin;
39380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3939a63bb30eSJed Brown   if (r) {
3940a63bb30eSJed Brown     if (!snes->vec_func) {
3941a63bb30eSJed Brown       if (snes->vec_rhs) {
3942a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3943a63bb30eSJed Brown       } else if (snes->vec_sol) {
3944a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3945a63bb30eSJed Brown       } else if (snes->dm) {
3946a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3947a63bb30eSJed Brown       }
3948a63bb30eSJed Brown     }
3949a63bb30eSJed Brown     *r = snes->vec_func;
3950a63bb30eSJed Brown   }
39516cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
39526cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
39533a40ed3dSBarry Smith   PetscFunctionReturn(0);
39549b94acceSBarry Smith }
39559b94acceSBarry Smith 
3956c79ef259SPeter Brune /*@C
3957c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3958c79ef259SPeter Brune 
3959c79ef259SPeter Brune    Input Parameter:
3960c79ef259SPeter Brune .  snes - the SNES context
3961c79ef259SPeter Brune 
3962c79ef259SPeter Brune    Output Parameter:
3963c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3964c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3965c79ef259SPeter Brune 
3966c79ef259SPeter Brune    Level: advanced
3967c79ef259SPeter Brune 
3968c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3969c79ef259SPeter Brune 
3970c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3971c79ef259SPeter Brune @*/
3972c79ef259SPeter Brune 
39734a2ae208SSatish Balay #undef __FUNCT__
3974646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3975646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3976646217ecSPeter Brune {
39776cab3a1bSJed Brown   PetscErrorCode ierr;
39786cab3a1bSJed Brown   DM             dm;
39796cab3a1bSJed Brown 
3980646217ecSPeter Brune   PetscFunctionBegin;
3981646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
39826cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
39836cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3984646217ecSPeter Brune   PetscFunctionReturn(0);
3985646217ecSPeter Brune }
3986646217ecSPeter Brune 
39874a2ae208SSatish Balay #undef __FUNCT__
39884a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
39893c7409f5SSatish Balay /*@C
39903c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3991d850072dSLois Curfman McInnes    SNES options in the database.
39923c7409f5SSatish Balay 
39933f9fe445SBarry Smith    Logically Collective on SNES
3994fee21e36SBarry Smith 
3995c7afd0dbSLois Curfman McInnes    Input Parameter:
3996c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3997c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3998c7afd0dbSLois Curfman McInnes 
3999d850072dSLois Curfman McInnes    Notes:
4000a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4001c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4002d850072dSLois Curfman McInnes 
400336851e7fSLois Curfman McInnes    Level: advanced
400436851e7fSLois Curfman McInnes 
40053c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
4006a86d99e1SLois Curfman McInnes 
4007a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
40083c7409f5SSatish Balay @*/
40097087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
40103c7409f5SSatish Balay {
4011dfbe8321SBarry Smith   PetscErrorCode ierr;
40123c7409f5SSatish Balay 
40133a40ed3dSBarry Smith   PetscFunctionBegin;
40140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4015639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
40161cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
401735f5d045SPeter Brune   if (snes->linesearch) {
401835f5d045SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
401908b6c495SPeter Brune     ierr = PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
402035f5d045SPeter Brune   }
402135f5d045SPeter Brune   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
40223a40ed3dSBarry Smith   PetscFunctionReturn(0);
40233c7409f5SSatish Balay }
40243c7409f5SSatish Balay 
40254a2ae208SSatish Balay #undef __FUNCT__
40264a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
40273c7409f5SSatish Balay /*@C
4028f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
4029d850072dSLois Curfman McInnes    SNES options in the database.
40303c7409f5SSatish Balay 
40313f9fe445SBarry Smith    Logically Collective on SNES
4032fee21e36SBarry Smith 
4033c7afd0dbSLois Curfman McInnes    Input Parameters:
4034c7afd0dbSLois Curfman McInnes +  snes - the SNES context
4035c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
4036c7afd0dbSLois Curfman McInnes 
4037d850072dSLois Curfman McInnes    Notes:
4038a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
4039c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
4040d850072dSLois Curfman McInnes 
404136851e7fSLois Curfman McInnes    Level: advanced
404236851e7fSLois Curfman McInnes 
40433c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
4044a86d99e1SLois Curfman McInnes 
4045a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
40463c7409f5SSatish Balay @*/
40477087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
40483c7409f5SSatish Balay {
4049dfbe8321SBarry Smith   PetscErrorCode ierr;
40503c7409f5SSatish Balay 
40513a40ed3dSBarry Smith   PetscFunctionBegin;
40520700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4053639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
40541cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
405535f5d045SPeter Brune   if (snes->linesearch) {
405635f5d045SPeter Brune     ierr = SNESGetSNESLineSearch(snes,&snes->linesearch);CHKERRQ(ierr);
405708b6c495SPeter Brune     ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix);CHKERRQ(ierr);
405835f5d045SPeter Brune   }
405935f5d045SPeter Brune   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
40603a40ed3dSBarry Smith   PetscFunctionReturn(0);
40613c7409f5SSatish Balay }
40623c7409f5SSatish Balay 
40634a2ae208SSatish Balay #undef __FUNCT__
40644a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
40659ab63eb5SSatish Balay /*@C
40663c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
40673c7409f5SSatish Balay    SNES options in the database.
40683c7409f5SSatish Balay 
4069c7afd0dbSLois Curfman McInnes    Not Collective
4070c7afd0dbSLois Curfman McInnes 
40713c7409f5SSatish Balay    Input Parameter:
40723c7409f5SSatish Balay .  snes - the SNES context
40733c7409f5SSatish Balay 
40743c7409f5SSatish Balay    Output Parameter:
40753c7409f5SSatish Balay .  prefix - pointer to the prefix string used
40763c7409f5SSatish Balay 
40774ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
40789ab63eb5SSatish Balay    sufficient length to hold the prefix.
40799ab63eb5SSatish Balay 
408036851e7fSLois Curfman McInnes    Level: advanced
408136851e7fSLois Curfman McInnes 
40823c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
4083a86d99e1SLois Curfman McInnes 
4084a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
40853c7409f5SSatish Balay @*/
40867087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
40873c7409f5SSatish Balay {
4088dfbe8321SBarry Smith   PetscErrorCode ierr;
40893c7409f5SSatish Balay 
40903a40ed3dSBarry Smith   PetscFunctionBegin;
40910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4092639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
40933a40ed3dSBarry Smith   PetscFunctionReturn(0);
40943c7409f5SSatish Balay }
40953c7409f5SSatish Balay 
4096b2002411SLois Curfman McInnes 
40974a2ae208SSatish Balay #undef __FUNCT__
40984a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
40993cea93caSBarry Smith /*@C
41003cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
41013cea93caSBarry Smith 
41027f6c08e0SMatthew Knepley   Level: advanced
41033cea93caSBarry Smith @*/
41047087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
4105b2002411SLois Curfman McInnes {
4106e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
4107dfbe8321SBarry Smith   PetscErrorCode ierr;
4108b2002411SLois Curfman McInnes 
4109b2002411SLois Curfman McInnes   PetscFunctionBegin;
4110b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
4111c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
4112b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
4113b2002411SLois Curfman McInnes }
4114da9b6338SBarry Smith 
4115da9b6338SBarry Smith #undef __FUNCT__
4116da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
41177087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
4118da9b6338SBarry Smith {
4119dfbe8321SBarry Smith   PetscErrorCode ierr;
412077431f27SBarry Smith   PetscInt       N,i,j;
4121da9b6338SBarry Smith   Vec            u,uh,fh;
4122da9b6338SBarry Smith   PetscScalar    value;
4123da9b6338SBarry Smith   PetscReal      norm;
4124da9b6338SBarry Smith 
4125da9b6338SBarry Smith   PetscFunctionBegin;
4126da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
4127da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
4128da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
4129da9b6338SBarry Smith 
4130da9b6338SBarry Smith   /* currently only works for sequential */
4131da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
4132da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
4133da9b6338SBarry Smith   for (i=0; i<N; i++) {
4134da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
413577431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
4136da9b6338SBarry Smith     for (j=-10; j<11; j++) {
4137ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
4138da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
41393ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
4140da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
414177431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
4142da9b6338SBarry Smith       value = -value;
4143da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
4144da9b6338SBarry Smith     }
4145da9b6338SBarry Smith   }
41466bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
41476bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
4148da9b6338SBarry Smith   PetscFunctionReturn(0);
4149da9b6338SBarry Smith }
415071f87433Sdalcinl 
415171f87433Sdalcinl #undef __FUNCT__
4152fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
415371f87433Sdalcinl /*@
4154fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
415571f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
415671f87433Sdalcinl    Newton method.
415771f87433Sdalcinl 
41583f9fe445SBarry Smith    Logically Collective on SNES
415971f87433Sdalcinl 
416071f87433Sdalcinl    Input Parameters:
416171f87433Sdalcinl +  snes - SNES context
416271f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
416371f87433Sdalcinl 
416464ba62caSBarry Smith     Options Database:
416564ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
416664ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
416764ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
416864ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
416964ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
417064ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
417164ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
417264ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
417364ba62caSBarry Smith 
417471f87433Sdalcinl    Notes:
417571f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
417671f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
417771f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
417871f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
417971f87433Sdalcinl    solver.
418071f87433Sdalcinl 
418171f87433Sdalcinl    Level: advanced
418271f87433Sdalcinl 
418371f87433Sdalcinl    Reference:
418471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
418571f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
418671f87433Sdalcinl 
418771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
418871f87433Sdalcinl 
4189fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
419071f87433Sdalcinl @*/
41917087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
419271f87433Sdalcinl {
419371f87433Sdalcinl   PetscFunctionBegin;
41940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4195acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
419671f87433Sdalcinl   snes->ksp_ewconv = flag;
419771f87433Sdalcinl   PetscFunctionReturn(0);
419871f87433Sdalcinl }
419971f87433Sdalcinl 
420071f87433Sdalcinl #undef __FUNCT__
4201fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
420271f87433Sdalcinl /*@
4203fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
420471f87433Sdalcinl    for computing relative tolerance for linear solvers within an
420571f87433Sdalcinl    inexact Newton method.
420671f87433Sdalcinl 
420771f87433Sdalcinl    Not Collective
420871f87433Sdalcinl 
420971f87433Sdalcinl    Input Parameter:
421071f87433Sdalcinl .  snes - SNES context
421171f87433Sdalcinl 
421271f87433Sdalcinl    Output Parameter:
421371f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
421471f87433Sdalcinl 
421571f87433Sdalcinl    Notes:
421671f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
421771f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
421871f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
421971f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
422071f87433Sdalcinl    solver.
422171f87433Sdalcinl 
422271f87433Sdalcinl    Level: advanced
422371f87433Sdalcinl 
422471f87433Sdalcinl    Reference:
422571f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
422671f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
422771f87433Sdalcinl 
422871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
422971f87433Sdalcinl 
4230fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
423171f87433Sdalcinl @*/
42327087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
423371f87433Sdalcinl {
423471f87433Sdalcinl   PetscFunctionBegin;
42350700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
423671f87433Sdalcinl   PetscValidPointer(flag,2);
423771f87433Sdalcinl   *flag = snes->ksp_ewconv;
423871f87433Sdalcinl   PetscFunctionReturn(0);
423971f87433Sdalcinl }
424071f87433Sdalcinl 
424171f87433Sdalcinl #undef __FUNCT__
4242fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
424371f87433Sdalcinl /*@
4244fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
424571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
424671f87433Sdalcinl    Newton method.
424771f87433Sdalcinl 
42483f9fe445SBarry Smith    Logically Collective on SNES
424971f87433Sdalcinl 
425071f87433Sdalcinl    Input Parameters:
425171f87433Sdalcinl +    snes - SNES context
425271f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
425371f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
425471f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
425571f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
425671f87433Sdalcinl              (0 <= gamma2 <= 1)
425771f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
425871f87433Sdalcinl .    alpha2 - power for safeguard
425971f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
426071f87433Sdalcinl 
426171f87433Sdalcinl    Note:
426271f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
426371f87433Sdalcinl 
426471f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
426571f87433Sdalcinl 
426671f87433Sdalcinl    Level: advanced
426771f87433Sdalcinl 
426871f87433Sdalcinl    Reference:
426971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
427071f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
427171f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
427271f87433Sdalcinl 
427371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
427471f87433Sdalcinl 
4275fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
427671f87433Sdalcinl @*/
42777087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
427871f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
427971f87433Sdalcinl {
4280fa9f3622SBarry Smith   SNESKSPEW *kctx;
428171f87433Sdalcinl   PetscFunctionBegin;
42820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4283fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4284e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4285c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4286c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4287c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4288c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4289c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4290c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4291c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
429271f87433Sdalcinl 
429371f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
429471f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
429571f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
429671f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
429771f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
429871f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
429971f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
430071f87433Sdalcinl 
430171f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4302e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
430371f87433Sdalcinl   }
430471f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4305e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
430671f87433Sdalcinl   }
430771f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4308e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
430971f87433Sdalcinl   }
431071f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4311e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
431271f87433Sdalcinl   }
431371f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4314e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
431571f87433Sdalcinl   }
431671f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4317e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
431871f87433Sdalcinl   }
431971f87433Sdalcinl   PetscFunctionReturn(0);
432071f87433Sdalcinl }
432171f87433Sdalcinl 
432271f87433Sdalcinl #undef __FUNCT__
4323fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
432471f87433Sdalcinl /*@
4325fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
432671f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
432771f87433Sdalcinl    Newton method.
432871f87433Sdalcinl 
432971f87433Sdalcinl    Not Collective
433071f87433Sdalcinl 
433171f87433Sdalcinl    Input Parameters:
433271f87433Sdalcinl      snes - SNES context
433371f87433Sdalcinl 
433471f87433Sdalcinl    Output Parameters:
433571f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
433671f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
433771f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
433871f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
433971f87433Sdalcinl              (0 <= gamma2 <= 1)
434071f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
434171f87433Sdalcinl .    alpha2 - power for safeguard
434271f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
434371f87433Sdalcinl 
434471f87433Sdalcinl    Level: advanced
434571f87433Sdalcinl 
434671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
434771f87433Sdalcinl 
4348fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
434971f87433Sdalcinl @*/
43507087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
435171f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
435271f87433Sdalcinl {
4353fa9f3622SBarry Smith   SNESKSPEW *kctx;
435471f87433Sdalcinl   PetscFunctionBegin;
43550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4356fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4357e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
435871f87433Sdalcinl   if (version)   *version   = kctx->version;
435971f87433Sdalcinl   if (rtol_0)    *rtol_0    = kctx->rtol_0;
436071f87433Sdalcinl   if (rtol_max)  *rtol_max  = kctx->rtol_max;
436171f87433Sdalcinl   if (gamma)     *gamma     = kctx->gamma;
436271f87433Sdalcinl   if (alpha)     *alpha     = kctx->alpha;
436371f87433Sdalcinl   if (alpha2)    *alpha2    = kctx->alpha2;
436471f87433Sdalcinl   if (threshold) *threshold = kctx->threshold;
436571f87433Sdalcinl   PetscFunctionReturn(0);
436671f87433Sdalcinl }
436771f87433Sdalcinl 
436871f87433Sdalcinl #undef __FUNCT__
4369fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4370fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
437171f87433Sdalcinl {
437271f87433Sdalcinl   PetscErrorCode ierr;
4373fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
437471f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
437571f87433Sdalcinl 
437671f87433Sdalcinl   PetscFunctionBegin;
4377e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
437871f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
437971f87433Sdalcinl     rtol = kctx->rtol_0;
438071f87433Sdalcinl   } else {
438171f87433Sdalcinl     if (kctx->version == 1) {
438271f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
438371f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
438471f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
438571f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
438671f87433Sdalcinl     } else if (kctx->version == 2) {
438771f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
438871f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
438971f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
439071f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
439171f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
439271f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
439371f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
439471f87433Sdalcinl       stol = PetscMax(rtol,stol);
439571f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
439671f87433Sdalcinl       /* safeguard: avoid oversolving */
439771f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
439871f87433Sdalcinl       stol = PetscMax(rtol,stol);
439971f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4400e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
440171f87433Sdalcinl   }
440271f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
440371f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
440471f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
440571f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
440671f87433Sdalcinl   PetscFunctionReturn(0);
440771f87433Sdalcinl }
440871f87433Sdalcinl 
440971f87433Sdalcinl #undef __FUNCT__
4410fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4411fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
441271f87433Sdalcinl {
441371f87433Sdalcinl   PetscErrorCode ierr;
4414fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
441571f87433Sdalcinl   PCSide         pcside;
441671f87433Sdalcinl   Vec            lres;
441771f87433Sdalcinl 
441871f87433Sdalcinl   PetscFunctionBegin;
4419e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
442071f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
442171f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
442271f87433Sdalcinl   if (kctx->version == 1) {
4423b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
442471f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
442571f87433Sdalcinl       /* KSP residual is true linear residual */
442671f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
442771f87433Sdalcinl     } else {
442871f87433Sdalcinl       /* KSP residual is preconditioned residual */
442971f87433Sdalcinl       /* compute true linear residual norm */
443071f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
443171f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
443271f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
443371f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
44346bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
443571f87433Sdalcinl     }
443671f87433Sdalcinl   }
443771f87433Sdalcinl   PetscFunctionReturn(0);
443871f87433Sdalcinl }
443971f87433Sdalcinl 
444071f87433Sdalcinl #undef __FUNCT__
444171f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
444271f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
444371f87433Sdalcinl {
444471f87433Sdalcinl   PetscErrorCode ierr;
444571f87433Sdalcinl 
444671f87433Sdalcinl   PetscFunctionBegin;
4447fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
444871f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4449fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
445071f87433Sdalcinl   PetscFunctionReturn(0);
445171f87433Sdalcinl }
44526c699258SBarry Smith 
4453b4615a05SBarry Smith #include <petsc-private/dmimpl.h>
44546c699258SBarry Smith #undef __FUNCT__
44556c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
44566c699258SBarry Smith /*@
44576c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
44586c699258SBarry Smith 
44593f9fe445SBarry Smith    Logically Collective on SNES
44606c699258SBarry Smith 
44616c699258SBarry Smith    Input Parameters:
44626c699258SBarry Smith +  snes - the preconditioner context
44636c699258SBarry Smith -  dm - the dm
44646c699258SBarry Smith 
44656c699258SBarry Smith    Level: intermediate
44666c699258SBarry Smith 
44676c699258SBarry Smith 
44686c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
44696c699258SBarry Smith @*/
44707087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
44716c699258SBarry Smith {
44726c699258SBarry Smith   PetscErrorCode ierr;
4473345fed2cSBarry Smith   KSP            ksp;
4474942e3340SBarry Smith   DMSNES         sdm;
44756c699258SBarry Smith 
44766c699258SBarry Smith   PetscFunctionBegin;
44770700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4478d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
4479942e3340SBarry Smith   if (snes->dm) {               /* Move the DMSNES context over to the new DM unless the new DM already has one */
4480b4615a05SBarry Smith     if (snes->dm->dmsnes && snes->dmAuto && !dm->dmsnes) {
4481942e3340SBarry Smith       ierr = DMCopyDMSNES(snes->dm,dm);CHKERRQ(ierr);
4482942e3340SBarry Smith       ierr = DMGetDMSNES(snes->dm,&sdm);CHKERRQ(ierr);
44836cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
44846cab3a1bSJed Brown         sdm->originaldm = dm;
44856cab3a1bSJed Brown       }
44866cab3a1bSJed Brown     }
44876bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
44886cab3a1bSJed Brown   }
44896c699258SBarry Smith   snes->dm = dm;
4490116d1032SJed Brown   snes->dmAuto = PETSC_FALSE;
4491345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4492345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4493f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
44942c155ee1SBarry Smith   if (snes->pc) {
44952c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
4496c40d0f55SPeter Brune     ierr = SNESSetPCSide(snes,snes->pcside);CHKERRQ(ierr);
44972c155ee1SBarry Smith   }
44986c699258SBarry Smith   PetscFunctionReturn(0);
44996c699258SBarry Smith }
45006c699258SBarry Smith 
45016c699258SBarry Smith #undef __FUNCT__
45026c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
45036c699258SBarry Smith /*@
45046c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
45056c699258SBarry Smith 
45063f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
45076c699258SBarry Smith 
45086c699258SBarry Smith    Input Parameter:
45096c699258SBarry Smith . snes - the preconditioner context
45106c699258SBarry Smith 
45116c699258SBarry Smith    Output Parameter:
45126c699258SBarry Smith .  dm - the dm
45136c699258SBarry Smith 
45146c699258SBarry Smith    Level: intermediate
45156c699258SBarry Smith 
45166c699258SBarry Smith 
45176c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
45186c699258SBarry Smith @*/
45197087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
45206c699258SBarry Smith {
45216cab3a1bSJed Brown   PetscErrorCode ierr;
45226cab3a1bSJed Brown 
45236c699258SBarry Smith   PetscFunctionBegin;
45240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
45256cab3a1bSJed Brown   if (!snes->dm) {
45266cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
4527116d1032SJed Brown     snes->dmAuto = PETSC_TRUE;
45286cab3a1bSJed Brown   }
45296c699258SBarry Smith   *dm = snes->dm;
45306c699258SBarry Smith   PetscFunctionReturn(0);
45316c699258SBarry Smith }
45320807856dSBarry Smith 
453331823bd8SMatthew G Knepley #undef __FUNCT__
453431823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
453531823bd8SMatthew G Knepley /*@
4536fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
453731823bd8SMatthew G Knepley 
453831823bd8SMatthew G Knepley   Collective on SNES
453931823bd8SMatthew G Knepley 
454031823bd8SMatthew G Knepley   Input Parameters:
454131823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
454231823bd8SMatthew G Knepley - pc   - the preconditioner object
454331823bd8SMatthew G Knepley 
454431823bd8SMatthew G Knepley   Notes:
454531823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
454631823bd8SMatthew G Knepley   to configure it using the API).
454731823bd8SMatthew G Knepley 
454831823bd8SMatthew G Knepley   Level: developer
454931823bd8SMatthew G Knepley 
455031823bd8SMatthew G Knepley .keywords: SNES, set, precondition
455131823bd8SMatthew G Knepley .seealso: SNESGetPC()
455231823bd8SMatthew G Knepley @*/
455331823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
455431823bd8SMatthew G Knepley {
455531823bd8SMatthew G Knepley   PetscErrorCode ierr;
455631823bd8SMatthew G Knepley 
455731823bd8SMatthew G Knepley   PetscFunctionBegin;
455831823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
455931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
456031823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
456131823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4562bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
456331823bd8SMatthew G Knepley   snes->pc = pc;
456431823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
456531823bd8SMatthew G Knepley   PetscFunctionReturn(0);
456631823bd8SMatthew G Knepley }
456731823bd8SMatthew G Knepley 
456831823bd8SMatthew G Knepley #undef __FUNCT__
456931823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
457031823bd8SMatthew G Knepley /*@
4571fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
457231823bd8SMatthew G Knepley 
457331823bd8SMatthew G Knepley   Not Collective
457431823bd8SMatthew G Knepley 
457531823bd8SMatthew G Knepley   Input Parameter:
457631823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
457731823bd8SMatthew G Knepley 
457831823bd8SMatthew G Knepley   Output Parameter:
457931823bd8SMatthew G Knepley . pc - preconditioner context
458031823bd8SMatthew G Knepley 
458131823bd8SMatthew G Knepley   Level: developer
458231823bd8SMatthew G Knepley 
458331823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
458431823bd8SMatthew G Knepley .seealso: SNESSetPC()
458531823bd8SMatthew G Knepley @*/
458631823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
458731823bd8SMatthew G Knepley {
458831823bd8SMatthew G Knepley   PetscErrorCode              ierr;
4589a64e098fSPeter Brune   const char                  *optionsprefix;
459031823bd8SMatthew G Knepley 
459131823bd8SMatthew G Knepley   PetscFunctionBegin;
459231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
459331823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
459431823bd8SMatthew G Knepley   if (!snes->pc) {
459531823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm,&snes->pc);CHKERRQ(ierr);
45964a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->pc,(PetscObject)snes,1);CHKERRQ(ierr);
459731823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes,snes->pc);CHKERRQ(ierr);
4598a64e098fSPeter Brune     ierr = SNESGetOptionsPrefix(snes,&optionsprefix);CHKERRQ(ierr);
4599a64e098fSPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc,optionsprefix);CHKERRQ(ierr);
4600a64e098fSPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc,"npc_");CHKERRQ(ierr);
460131823bd8SMatthew G Knepley   }
460231823bd8SMatthew G Knepley   *pc = snes->pc;
460331823bd8SMatthew G Knepley   PetscFunctionReturn(0);
460431823bd8SMatthew G Knepley }
460531823bd8SMatthew G Knepley 
4606c40d0f55SPeter Brune 
4607c40d0f55SPeter Brune #undef __FUNCT__
4608c40d0f55SPeter Brune #define __FUNCT__ "SNESSetPCSide"
4609c40d0f55SPeter Brune /*@
4610c40d0f55SPeter Brune     SNESSetPCSide - Sets the preconditioning side.
4611c40d0f55SPeter Brune 
4612c40d0f55SPeter Brune     Logically Collective on SNES
4613c40d0f55SPeter Brune 
4614c40d0f55SPeter Brune     Input Parameter:
4615c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4616c40d0f55SPeter Brune 
4617c40d0f55SPeter Brune     Output Parameter:
4618c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4619c40d0f55SPeter Brune .vb
4620c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4621c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4622c40d0f55SPeter Brune .ve
4623c40d0f55SPeter Brune 
4624c40d0f55SPeter Brune     Options Database Keys:
4625c40d0f55SPeter Brune .   -snes_pc_side <right,left>
4626c40d0f55SPeter Brune 
4627c40d0f55SPeter Brune     Level: intermediate
4628c40d0f55SPeter Brune 
4629c40d0f55SPeter Brune .keywords: SNES, set, right, left, side, preconditioner, flag
4630c40d0f55SPeter Brune 
4631c40d0f55SPeter Brune .seealso: SNESGetPCSide(), KSPSetPCSide()
4632c40d0f55SPeter Brune @*/
4633c40d0f55SPeter Brune PetscErrorCode  SNESSetPCSide(SNES snes,PCSide side)
4634c40d0f55SPeter Brune {
4635c40d0f55SPeter Brune   PetscFunctionBegin;
4636c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4637c40d0f55SPeter Brune   PetscValidLogicalCollectiveEnum(snes,side,2);
4638c40d0f55SPeter Brune   snes->pcside = side;
4639c40d0f55SPeter Brune   PetscFunctionReturn(0);
4640c40d0f55SPeter Brune }
4641c40d0f55SPeter Brune 
4642c40d0f55SPeter Brune #undef __FUNCT__
4643c40d0f55SPeter Brune #define __FUNCT__ "SNESGetPCSide"
4644c40d0f55SPeter Brune /*@
4645c40d0f55SPeter Brune     SNESGetPCSide - Gets the preconditioning side.
4646c40d0f55SPeter Brune 
4647c40d0f55SPeter Brune     Not Collective
4648c40d0f55SPeter Brune 
4649c40d0f55SPeter Brune     Input Parameter:
4650c40d0f55SPeter Brune .   snes - iterative context obtained from SNESCreate()
4651c40d0f55SPeter Brune 
4652c40d0f55SPeter Brune     Output Parameter:
4653c40d0f55SPeter Brune .   side - the preconditioning side, where side is one of
4654c40d0f55SPeter Brune .vb
4655c40d0f55SPeter Brune       PC_LEFT - left preconditioning (default)
4656c40d0f55SPeter Brune       PC_RIGHT - right preconditioning
4657c40d0f55SPeter Brune .ve
4658c40d0f55SPeter Brune 
4659c40d0f55SPeter Brune     Level: intermediate
4660c40d0f55SPeter Brune 
4661c40d0f55SPeter Brune .keywords: SNES, get, right, left, side, preconditioner, flag
4662c40d0f55SPeter Brune 
4663c40d0f55SPeter Brune .seealso: SNESSetPCSide(), KSPGetPCSide()
4664c40d0f55SPeter Brune @*/
4665c40d0f55SPeter Brune PetscErrorCode  SNESGetPCSide(SNES snes,PCSide *side)
4666c40d0f55SPeter Brune {
4667c40d0f55SPeter Brune   PetscFunctionBegin;
4668c40d0f55SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4669c40d0f55SPeter Brune   PetscValidPointer(side,2);
4670c40d0f55SPeter Brune   *side = snes->pcside;
4671c40d0f55SPeter Brune   PetscFunctionReturn(0);
4672c40d0f55SPeter Brune }
4673c40d0f55SPeter Brune 
46749e764e56SPeter Brune #undef __FUNCT__
4675f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
46769e764e56SPeter Brune /*@
46778141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
46789e764e56SPeter Brune 
46799e764e56SPeter Brune   Collective on SNES
46809e764e56SPeter Brune 
46819e764e56SPeter Brune   Input Parameters:
46829e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
46839e764e56SPeter Brune - linesearch   - the linesearch object
46849e764e56SPeter Brune 
46859e764e56SPeter Brune   Notes:
4686f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
46879e764e56SPeter Brune   to configure it using the API).
46889e764e56SPeter Brune 
46899e764e56SPeter Brune   Level: developer
46909e764e56SPeter Brune 
46919e764e56SPeter Brune .keywords: SNES, set, linesearch
4692f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
46939e764e56SPeter Brune @*/
4694f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
46959e764e56SPeter Brune {
46969e764e56SPeter Brune   PetscErrorCode ierr;
46979e764e56SPeter Brune 
46989e764e56SPeter Brune   PetscFunctionBegin;
46999e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4700f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
47019e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
47029e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4703f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
47049e764e56SPeter Brune   snes->linesearch = linesearch;
47059e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
47069e764e56SPeter Brune   PetscFunctionReturn(0);
47079e764e56SPeter Brune }
47089e764e56SPeter Brune 
47099e764e56SPeter Brune #undef __FUNCT__
4710f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4711ea5d4fccSPeter Brune /*@C
47128141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
47138141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
47149e764e56SPeter Brune 
47159e764e56SPeter Brune   Not Collective
47169e764e56SPeter Brune 
47179e764e56SPeter Brune   Input Parameter:
47189e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
47199e764e56SPeter Brune 
47209e764e56SPeter Brune   Output Parameter:
47219e764e56SPeter Brune . linesearch - linesearch context
47229e764e56SPeter Brune 
47239e764e56SPeter Brune   Level: developer
47249e764e56SPeter Brune 
47259e764e56SPeter Brune .keywords: SNES, get, linesearch
4726f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
47279e764e56SPeter Brune @*/
4728f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
47299e764e56SPeter Brune {
47309e764e56SPeter Brune   PetscErrorCode ierr;
47319e764e56SPeter Brune   const char     *optionsprefix;
47329e764e56SPeter Brune 
47339e764e56SPeter Brune   PetscFunctionBegin;
47349e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
47359e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
47369e764e56SPeter Brune   if (!snes->linesearch) {
47379e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4738f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4739f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4740b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
47419e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
47429e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
47439e764e56SPeter Brune   }
47449e764e56SPeter Brune   *linesearch = snes->linesearch;
47459e764e56SPeter Brune   PetscFunctionReturn(0);
47469e764e56SPeter Brune }
47479e764e56SPeter Brune 
474869b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4749c6db04a5SJed Brown #include <mex.h>
475069b4f73cSBarry Smith 
47518f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
47528f6e6473SBarry Smith 
47530807856dSBarry Smith #undef __FUNCT__
47540807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
47550807856dSBarry Smith /*
47560807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
47570807856dSBarry Smith                          SNESSetFunctionMatlab().
47580807856dSBarry Smith 
47590807856dSBarry Smith    Collective on SNES
47600807856dSBarry Smith 
47610807856dSBarry Smith    Input Parameters:
47620807856dSBarry Smith +  snes - the SNES context
47630807856dSBarry Smith -  x - input vector
47640807856dSBarry Smith 
47650807856dSBarry Smith    Output Parameter:
47660807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
47670807856dSBarry Smith 
47680807856dSBarry Smith    Notes:
47690807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
47700807856dSBarry Smith    implementations, so most users would not generally call this routine
47710807856dSBarry Smith    themselves.
47720807856dSBarry Smith 
47730807856dSBarry Smith    Level: developer
47740807856dSBarry Smith 
47750807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
47760807856dSBarry Smith 
47770807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
477861b2408cSBarry Smith */
47797087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
47800807856dSBarry Smith {
4781e650e774SBarry Smith   PetscErrorCode    ierr;
47828f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
47838f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
47848f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
478591621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4786e650e774SBarry Smith 
47870807856dSBarry Smith   PetscFunctionBegin;
47880807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
47890807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
47900807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
47910807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
47920807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
47930807856dSBarry Smith 
47940807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4795e650e774SBarry Smith 
479691621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4797e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4798e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
479991621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
480091621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
480191621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
48028f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
48038f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4804b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4805e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4806e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4807e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4808e650e774SBarry Smith   mxDestroyArray(prhs[2]);
48098f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4810e650e774SBarry Smith   mxDestroyArray(plhs[0]);
48110807856dSBarry Smith   PetscFunctionReturn(0);
48120807856dSBarry Smith }
48130807856dSBarry Smith 
48140807856dSBarry Smith 
48150807856dSBarry Smith #undef __FUNCT__
48160807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
481761b2408cSBarry Smith /*
48180807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
48190807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4820e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
48210807856dSBarry Smith 
48220807856dSBarry Smith    Logically Collective on SNES
48230807856dSBarry Smith 
48240807856dSBarry Smith    Input Parameters:
48250807856dSBarry Smith +  snes - the SNES context
48260807856dSBarry Smith .  r - vector to store function value
48270807856dSBarry Smith -  func - function evaluation routine
48280807856dSBarry Smith 
48290807856dSBarry Smith    Calling sequence of func:
483061b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
48310807856dSBarry Smith 
48320807856dSBarry Smith 
48330807856dSBarry Smith    Notes:
48340807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
48350807856dSBarry Smith $      f'(x) x = -f(x),
48360807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
48370807856dSBarry Smith 
48380807856dSBarry Smith    Level: beginner
48390807856dSBarry Smith 
48400807856dSBarry Smith .keywords: SNES, nonlinear, set, function
48410807856dSBarry Smith 
48420807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
484361b2408cSBarry Smith */
48447087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
48450807856dSBarry Smith {
48460807856dSBarry Smith   PetscErrorCode    ierr;
48478f6e6473SBarry Smith   SNESMatlabContext *sctx;
48480807856dSBarry Smith 
48490807856dSBarry Smith   PetscFunctionBegin;
48508f6e6473SBarry Smith   /* currently sctx is memory bleed */
48518f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
48528f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
48538f6e6473SBarry Smith   /*
48548f6e6473SBarry Smith      This should work, but it doesn't
48558f6e6473SBarry Smith   sctx->ctx = ctx;
48568f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
48578f6e6473SBarry Smith   */
48588f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
48598f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
48600807856dSBarry Smith   PetscFunctionReturn(0);
48610807856dSBarry Smith }
486269b4f73cSBarry Smith 
486361b2408cSBarry Smith #undef __FUNCT__
486461b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
486561b2408cSBarry Smith /*
486661b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
486761b2408cSBarry Smith                          SNESSetJacobianMatlab().
486861b2408cSBarry Smith 
486961b2408cSBarry Smith    Collective on SNES
487061b2408cSBarry Smith 
487161b2408cSBarry Smith    Input Parameters:
487261b2408cSBarry Smith +  snes - the SNES context
487361b2408cSBarry Smith .  x - input vector
487461b2408cSBarry Smith .  A, B - the matrices
487561b2408cSBarry Smith -  ctx - user context
487661b2408cSBarry Smith 
487761b2408cSBarry Smith    Output Parameter:
487861b2408cSBarry Smith .  flag - structure of the matrix
487961b2408cSBarry Smith 
488061b2408cSBarry Smith    Level: developer
488161b2408cSBarry Smith 
488261b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
488361b2408cSBarry Smith 
488461b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
488561b2408cSBarry Smith @*/
48867087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
488761b2408cSBarry Smith {
488861b2408cSBarry Smith   PetscErrorCode    ierr;
488961b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
489061b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
489161b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
489261b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
489361b2408cSBarry Smith 
489461b2408cSBarry Smith   PetscFunctionBegin;
489561b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
489661b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
489761b2408cSBarry Smith 
489861b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
489961b2408cSBarry Smith 
490061b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
490161b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
490261b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
490361b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
490461b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
490561b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
490661b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
490761b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
490861b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
490961b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4910b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
491161b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
491261b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
491361b2408cSBarry Smith   mxDestroyArray(prhs[0]);
491461b2408cSBarry Smith   mxDestroyArray(prhs[1]);
491561b2408cSBarry Smith   mxDestroyArray(prhs[2]);
491661b2408cSBarry Smith   mxDestroyArray(prhs[3]);
491761b2408cSBarry Smith   mxDestroyArray(prhs[4]);
491861b2408cSBarry Smith   mxDestroyArray(plhs[0]);
491961b2408cSBarry Smith   mxDestroyArray(plhs[1]);
492061b2408cSBarry Smith   PetscFunctionReturn(0);
492161b2408cSBarry Smith }
492261b2408cSBarry Smith 
492361b2408cSBarry Smith 
492461b2408cSBarry Smith #undef __FUNCT__
492561b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
492661b2408cSBarry Smith /*
492761b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
492861b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4929e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
493061b2408cSBarry Smith 
493161b2408cSBarry Smith    Logically Collective on SNES
493261b2408cSBarry Smith 
493361b2408cSBarry Smith    Input Parameters:
493461b2408cSBarry Smith +  snes - the SNES context
493561b2408cSBarry Smith .  A,B - Jacobian matrices
493661b2408cSBarry Smith .  func - function evaluation routine
493761b2408cSBarry Smith -  ctx - user context
493861b2408cSBarry Smith 
493961b2408cSBarry Smith    Calling sequence of func:
494061b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
494161b2408cSBarry Smith 
494261b2408cSBarry Smith 
494361b2408cSBarry Smith    Level: developer
494461b2408cSBarry Smith 
494561b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
494661b2408cSBarry Smith 
494761b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
494861b2408cSBarry Smith */
49497087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
495061b2408cSBarry Smith {
495161b2408cSBarry Smith   PetscErrorCode    ierr;
495261b2408cSBarry Smith   SNESMatlabContext *sctx;
495361b2408cSBarry Smith 
495461b2408cSBarry Smith   PetscFunctionBegin;
495561b2408cSBarry Smith   /* currently sctx is memory bleed */
495661b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
495761b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
495861b2408cSBarry Smith   /*
495961b2408cSBarry Smith      This should work, but it doesn't
496061b2408cSBarry Smith   sctx->ctx = ctx;
496161b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
496261b2408cSBarry Smith   */
496361b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
496461b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
496561b2408cSBarry Smith   PetscFunctionReturn(0);
496661b2408cSBarry Smith }
496769b4f73cSBarry Smith 
4968f9eb7ae2SShri Abhyankar #undef __FUNCT__
4969f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4970f9eb7ae2SShri Abhyankar /*
4971f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4972f9eb7ae2SShri Abhyankar 
4973f9eb7ae2SShri Abhyankar    Collective on SNES
4974f9eb7ae2SShri Abhyankar 
4975f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4976f9eb7ae2SShri Abhyankar @*/
49777087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4978f9eb7ae2SShri Abhyankar {
4979f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
498048f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4981f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4982f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4983f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4984f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4985f9eb7ae2SShri Abhyankar 
4986f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4987f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4988f9eb7ae2SShri Abhyankar 
4989f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4990f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4991f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4992f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4993f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4994f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4995f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4996f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4997f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4998f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4999f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
5000f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
5001f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
5002f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
5003f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
5004f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
5005f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5006f9eb7ae2SShri Abhyankar }
5007f9eb7ae2SShri Abhyankar 
5008f9eb7ae2SShri Abhyankar 
5009f9eb7ae2SShri Abhyankar #undef __FUNCT__
5010f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
5011f9eb7ae2SShri Abhyankar /*
5012e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
5013f9eb7ae2SShri Abhyankar 
5014f9eb7ae2SShri Abhyankar    Level: developer
5015f9eb7ae2SShri Abhyankar 
5016f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
5017f9eb7ae2SShri Abhyankar 
5018f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
5019f9eb7ae2SShri Abhyankar */
50207087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
5021f9eb7ae2SShri Abhyankar {
5022f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
5023f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
5024f9eb7ae2SShri Abhyankar 
5025f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
5026f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
5027f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
5028f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
5029f9eb7ae2SShri Abhyankar   /*
5030f9eb7ae2SShri Abhyankar      This should work, but it doesn't
5031f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
5032f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
5033f9eb7ae2SShri Abhyankar   */
5034f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
5035f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
5036f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
5037f9eb7ae2SShri Abhyankar }
5038f9eb7ae2SShri Abhyankar 
503969b4f73cSBarry Smith #endif
5040