xref: /petsc/src/snes/interface/snes.c (revision ea5d4fccf296dd2bbd0f9c3a3343651cb1066da7)
19b94acceSBarry Smith 
2c6db04a5SJed Brown #include <private/snesimpl.h>      /*I "petscsnes.h"  I*/
36cab3a1bSJed Brown #include <petscdmshell.h>          /*I "petscdmshell.h" I*/
49b94acceSBarry Smith 
5ace3abfcSBarry Smith PetscBool  SNESRegisterAllCalled = PETSC_FALSE;
68ba1e511SMatthew Knepley PetscFList SNESList              = PETSC_NULL;
78ba1e511SMatthew Knepley 
88ba1e511SMatthew Knepley /* Logging support */
97087cfbeSBarry Smith PetscClassId  SNES_CLASSID;
10701cf23dSPeter Brune PetscLogEvent  SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13cab2e9ccSBarry Smith #define __FUNCT__ "SNESDMComputeJacobian"
14cab2e9ccSBarry Smith /*
15cab2e9ccSBarry Smith     Translates from a SNES call to a DM call in computing a Jacobian
16cab2e9ccSBarry Smith */
17cab2e9ccSBarry Smith PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
18cab2e9ccSBarry Smith {
19cab2e9ccSBarry Smith   PetscErrorCode ierr;
20cab2e9ccSBarry Smith   DM             dm;
21cab2e9ccSBarry Smith 
22cab2e9ccSBarry Smith   PetscFunctionBegin;
23cab2e9ccSBarry Smith   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
24cab2e9ccSBarry Smith   ierr = DMComputeJacobian(dm,X,*J,*B,flag);CHKERRQ(ierr);
25cab2e9ccSBarry Smith   PetscFunctionReturn(0);
26cab2e9ccSBarry Smith }
27cab2e9ccSBarry Smith 
28cab2e9ccSBarry Smith #undef __FUNCT__
29e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
30e113a28aSBarry Smith /*@
31e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
32e113a28aSBarry Smith 
333f9fe445SBarry Smith    Logically Collective on SNES
34e113a28aSBarry Smith 
35e113a28aSBarry Smith    Input Parameters:
36e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
37e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
38e113a28aSBarry Smith 
39e113a28aSBarry Smith    Options database keys:
40e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
41e113a28aSBarry Smith 
42e113a28aSBarry Smith    Level: intermediate
43e113a28aSBarry Smith 
44e113a28aSBarry Smith    Notes:
45e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
46e113a28aSBarry Smith     to determine if it has converged.
47e113a28aSBarry Smith 
48e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
49e113a28aSBarry Smith 
50e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
51e113a28aSBarry Smith @*/
527087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
53e113a28aSBarry Smith {
54e113a28aSBarry Smith   PetscFunctionBegin;
55e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
56acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
57e113a28aSBarry Smith   snes->errorifnotconverged = flg;
58dd568438SSatish Balay 
59e113a28aSBarry Smith   PetscFunctionReturn(0);
60e113a28aSBarry Smith }
61e113a28aSBarry Smith 
62e113a28aSBarry Smith #undef __FUNCT__
63e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
64e113a28aSBarry Smith /*@
65e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
66e113a28aSBarry Smith 
67e113a28aSBarry Smith    Not Collective
68e113a28aSBarry Smith 
69e113a28aSBarry Smith    Input Parameter:
70e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
71e113a28aSBarry Smith 
72e113a28aSBarry Smith    Output Parameter:
73e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
74e113a28aSBarry Smith 
75e113a28aSBarry Smith    Level: intermediate
76e113a28aSBarry Smith 
77e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
78e113a28aSBarry Smith 
79e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
80e113a28aSBarry Smith @*/
817087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
82e113a28aSBarry Smith {
83e113a28aSBarry Smith   PetscFunctionBegin;
84e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
85e113a28aSBarry Smith   PetscValidPointer(flag,2);
86e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
87e113a28aSBarry Smith   PetscFunctionReturn(0);
88e113a28aSBarry Smith }
89e113a28aSBarry Smith 
90e113a28aSBarry Smith #undef __FUNCT__
914936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
92e725d27bSBarry Smith /*@
934936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
944936397dSBarry Smith      in the functions domain. For example, negative pressure.
954936397dSBarry Smith 
963f9fe445SBarry Smith    Logically Collective on SNES
974936397dSBarry Smith 
984936397dSBarry Smith    Input Parameters:
996a388c36SPeter Brune .  snes - the SNES context
1004936397dSBarry Smith 
10128529972SSatish Balay    Level: advanced
1024936397dSBarry Smith 
1034936397dSBarry Smith .keywords: SNES, view
1044936397dSBarry Smith 
1054936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
1064936397dSBarry Smith @*/
1077087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
1084936397dSBarry Smith {
1094936397dSBarry Smith   PetscFunctionBegin;
1100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1114936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
1124936397dSBarry Smith   PetscFunctionReturn(0);
1134936397dSBarry Smith }
1144936397dSBarry Smith 
1156a388c36SPeter Brune 
1166a388c36SPeter Brune #undef __FUNCT__
1176a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1186a388c36SPeter Brune /*@
119c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1206a388c36SPeter Brune 
1216a388c36SPeter Brune    Logically Collective on SNES
1226a388c36SPeter Brune 
1236a388c36SPeter Brune    Input Parameters:
1246a388c36SPeter Brune .  snes - the SNES context
1256a388c36SPeter Brune 
1266a388c36SPeter Brune    Output Parameters:
1276a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1286a388c36SPeter Brune 
1296a388c36SPeter Brune    Level: advanced
1306a388c36SPeter Brune 
1316a388c36SPeter Brune .keywords: SNES, view
1326a388c36SPeter Brune 
1336a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1346a388c36SPeter Brune @*/
1356a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1366a388c36SPeter Brune {
1376a388c36SPeter Brune   PetscFunctionBegin;
1386a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1396a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1406a388c36SPeter Brune   *domainerror = snes->domainerror;
1416a388c36SPeter Brune   PetscFunctionReturn(0);
1426a388c36SPeter Brune }
1436a388c36SPeter Brune 
1446a388c36SPeter Brune 
1454936397dSBarry Smith #undef __FUNCT__
1464a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1477e2c5f70SBarry Smith /*@C
1489b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1499b94acceSBarry Smith 
1504c49b128SBarry Smith    Collective on SNES
151fee21e36SBarry Smith 
152c7afd0dbSLois Curfman McInnes    Input Parameters:
153c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
154c7afd0dbSLois Curfman McInnes -  viewer - visualization context
155c7afd0dbSLois Curfman McInnes 
1569b94acceSBarry Smith    Options Database Key:
157c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1589b94acceSBarry Smith 
1599b94acceSBarry Smith    Notes:
1609b94acceSBarry Smith    The available visualization contexts include
161b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
162b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
163c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
164c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
165c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1669b94acceSBarry Smith 
1673e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
168b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1699b94acceSBarry Smith 
17036851e7fSLois Curfman McInnes    Level: beginner
17136851e7fSLois Curfman McInnes 
1729b94acceSBarry Smith .keywords: SNES, view
1739b94acceSBarry Smith 
174b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1759b94acceSBarry Smith @*/
1767087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1779b94acceSBarry Smith {
178fa9f3622SBarry Smith   SNESKSPEW           *kctx;
179dfbe8321SBarry Smith   PetscErrorCode      ierr;
18094b7f48cSBarry Smith   KSP                 ksp;
181ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1829b94acceSBarry Smith 
1833a40ed3dSBarry Smith   PetscFunctionBegin;
1840700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1853050cee2SBarry Smith   if (!viewer) {
1867adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1873050cee2SBarry Smith   }
1880700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
189c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
19074679c65SBarry Smith 
1912692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
1922692d6eeSBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
19332077d6dSBarry Smith   if (iascii) {
194317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
195e7788613SBarry Smith     if (snes->ops->view) {
196b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
197e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
198b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1990ef38995SBarry Smith     }
20077431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
201a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
20270441072SBarry Smith                  snes->rtol,snes->abstol,snes->xtol);CHKERRQ(ierr);
20377431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
20477431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
2059b94acceSBarry Smith     if (snes->ksp_ewconv) {
206fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
2079b94acceSBarry Smith       if (kctx) {
20877431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
209a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
210a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
2119b94acceSBarry Smith       }
2129b94acceSBarry Smith     }
213eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
214eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
215eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
216eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
217eb1f6c34SBarry Smith     }
218eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
219eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
220eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
22142f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
222eb1f6c34SBarry Smith     }
2230f5bd95cSBarry Smith   } else if (isstring) {
224317d6ea6SBarry Smith     const char *type;
225454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
226b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
22719bcc07fSBarry Smith   }
22842f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2294a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2304a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2314a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2324a0c5b0cSMatthew G Knepley   }
2332c155ee1SBarry Smith   if (snes->usesksp) {
2342c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
235b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
23694b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
237b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2382c155ee1SBarry Smith   }
2399e764e56SPeter Brune   ierr = PetscViewerASCIIPrintf(viewer, "  line search variant: %s\n",((PetscObject)snes->linesearch)->type_name);CHKERRQ(ierr);
2403a40ed3dSBarry Smith   PetscFunctionReturn(0);
2419b94acceSBarry Smith }
2429b94acceSBarry Smith 
24376b2cf59SMatthew Knepley /*
24476b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
24576b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
24676b2cf59SMatthew Knepley */
24776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
248a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2496849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
25076b2cf59SMatthew Knepley 
251e74ef692SMatthew Knepley #undef __FUNCT__
252e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
253ac226902SBarry Smith /*@C
25476b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
25576b2cf59SMatthew Knepley 
25676b2cf59SMatthew Knepley   Not Collective
25776b2cf59SMatthew Knepley 
25876b2cf59SMatthew Knepley   Input Parameter:
25976b2cf59SMatthew Knepley . snescheck - function that checks for options
26076b2cf59SMatthew Knepley 
26176b2cf59SMatthew Knepley   Level: developer
26276b2cf59SMatthew Knepley 
26376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
26476b2cf59SMatthew Knepley @*/
2657087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
26676b2cf59SMatthew Knepley {
26776b2cf59SMatthew Knepley   PetscFunctionBegin;
26876b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
269e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
27076b2cf59SMatthew Knepley   }
27176b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
27276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
27376b2cf59SMatthew Knepley }
27476b2cf59SMatthew Knepley 
2757087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
276aa3661deSLisandro Dalcin 
277aa3661deSLisandro Dalcin #undef __FUNCT__
278aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
279ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
280aa3661deSLisandro Dalcin {
281aa3661deSLisandro Dalcin   Mat            J;
282aa3661deSLisandro Dalcin   KSP            ksp;
283aa3661deSLisandro Dalcin   PC             pc;
284ace3abfcSBarry Smith   PetscBool      match;
285aa3661deSLisandro Dalcin   PetscErrorCode ierr;
286aa3661deSLisandro Dalcin 
287aa3661deSLisandro Dalcin   PetscFunctionBegin;
2880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
289aa3661deSLisandro Dalcin 
29098613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
29198613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
29298613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
29398613b67SLisandro Dalcin   }
29498613b67SLisandro Dalcin 
295aa3661deSLisandro Dalcin   if (version == 1) {
296aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
29798613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2989c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
299aa3661deSLisandro Dalcin   } else if (version == 2) {
300e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
30182a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
302aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
303aa3661deSLisandro Dalcin #else
304e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
305aa3661deSLisandro Dalcin #endif
306a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
307aa3661deSLisandro Dalcin 
308aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
309d3462f78SMatthew Knepley   if (hasOperator) {
310aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
311aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
312aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
313aa3661deSLisandro Dalcin   } else {
314aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
315aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3166cab3a1bSJed Brown     void *functx;
3176cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3186cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
319aa3661deSLisandro Dalcin     /* Force no preconditioner */
320aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
321aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
322aa3661deSLisandro Dalcin     ierr = PetscTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
323aa3661deSLisandro Dalcin     if (!match) {
324aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
325aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
326aa3661deSLisandro Dalcin     }
327aa3661deSLisandro Dalcin   }
3286bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
329aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
330aa3661deSLisandro Dalcin }
331aa3661deSLisandro Dalcin 
3324a2ae208SSatish Balay #undef __FUNCT__
3336cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3346cab3a1bSJed Brown /*@
3356cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3366cab3a1bSJed Brown 
3376cab3a1bSJed Brown    Collective
3386cab3a1bSJed Brown 
3396cab3a1bSJed Brown    Input Arguments:
3406cab3a1bSJed Brown .  snes - snes to configure
3416cab3a1bSJed Brown 
3426cab3a1bSJed Brown    Level: developer
3436cab3a1bSJed Brown 
3446cab3a1bSJed Brown .seealso: SNESSetUp()
3456cab3a1bSJed Brown @*/
3466cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3476cab3a1bSJed Brown {
3486cab3a1bSJed Brown   PetscErrorCode ierr;
3496cab3a1bSJed Brown   DM             dm;
3506cab3a1bSJed Brown   SNESDM         sdm;
3516cab3a1bSJed Brown 
3526cab3a1bSJed Brown   PetscFunctionBegin;
3536cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3546cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
3556cab3a1bSJed Brown   if (!sdm->computejacobian && snes->dm) {
3566cab3a1bSJed Brown     Mat J,B;
3576cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3586cab3a1bSJed Brown     if (snes->mf_operator) {
3596cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3606cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3616cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3626cab3a1bSJed Brown     } else {
3636cab3a1bSJed Brown       J = B;
3646cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
3656cab3a1bSJed Brown     }
3666cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
3676cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3686cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3696cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
3706cab3a1bSJed Brown     Mat J;
3716cab3a1bSJed Brown     void *functx;
3726cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3736cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3746cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3756cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3766cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
3776cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3786cab3a1bSJed Brown   } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
3796cab3a1bSJed Brown     Mat J,B;
3806cab3a1bSJed Brown     void *functx;
3816cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
3826cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
3836cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
3846cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3856cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3866cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
3876cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
3886cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3896cab3a1bSJed Brown   } else if (snes->dm && !snes->jacobian_pre) {
3906cab3a1bSJed Brown     Mat J,B;
3916cab3a1bSJed Brown     J = snes->jacobian;
3926cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3936cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
3946cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
3956cab3a1bSJed Brown   }
3966cab3a1bSJed Brown   PetscFunctionReturn(0);
3976cab3a1bSJed Brown }
3986cab3a1bSJed Brown 
3996cab3a1bSJed Brown #undef __FUNCT__
4004a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4019b94acceSBarry Smith /*@
40294b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4039b94acceSBarry Smith 
404c7afd0dbSLois Curfman McInnes    Collective on SNES
405c7afd0dbSLois Curfman McInnes 
4069b94acceSBarry Smith    Input Parameter:
4079b94acceSBarry Smith .  snes - the SNES context
4089b94acceSBarry Smith 
40936851e7fSLois Curfman McInnes    Options Database Keys:
410ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
41182738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
41282738288SBarry Smith                 of the change in the solution between steps
41370441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
414b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
415b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
416b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4174839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
418ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
419a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
420e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
421b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4222492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
42382738288SBarry Smith                                solver; hence iterations will continue until max_it
4241fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
42582738288SBarry Smith                                of convergence test
426e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
427e8105e01SRichard Katz                                        filename given prints to stdout
428a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
429a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
430a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
431a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
432e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4335968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
434fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
43582738288SBarry Smith 
43682738288SBarry Smith     Options Database for Eisenstat-Walker method:
437fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4384b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
43936851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
44036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
44136851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
44236851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
44336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
44436851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
44582738288SBarry Smith 
44611ca99fdSLois Curfman McInnes    Notes:
44711ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4480598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
44983e2fdc7SBarry Smith 
45036851e7fSLois Curfman McInnes    Level: beginner
45136851e7fSLois Curfman McInnes 
4529b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
4539b94acceSBarry Smith 
45469ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
4559b94acceSBarry Smith @*/
4567087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
4579b94acceSBarry Smith {
458ea630c6eSPeter Brune   PetscBool               flg,set,mf,mf_operator,pcset;
459efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
460aa3661deSLisandro Dalcin   MatStructure            matflag;
46185385478SLisandro Dalcin   const char              *deft = SNESLS;
46285385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
46385385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
464e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
46551e86f29SPeter Brune   const char              *optionsprefix;
466649052a6SBarry Smith   PetscViewer             monviewer;
46785385478SLisandro Dalcin   PetscErrorCode          ierr;
4689b94acceSBarry Smith 
4693a40ed3dSBarry Smith   PetscFunctionBegin;
4700700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
471ca161407SBarry Smith 
472186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
4733194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
4747adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
475b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
476d64ed03dSBarry Smith     if (flg) {
477186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
4787adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
479186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
480d64ed03dSBarry Smith     }
48190d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
482909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
48393c39befSBarry Smith 
48457034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);CHKERRQ(ierr);
48557034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
486186905e3SBarry Smith 
48757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
488b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
489b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
49050ffb88aSMatthew Knepley     ierr = PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
491ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
492acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
49385385478SLisandro Dalcin 
494a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
495a8054027SBarry Smith     if (flg) {
496a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
497a8054027SBarry Smith     }
498e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
499e35cf81dSBarry Smith     if (flg) {
500e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
501e35cf81dSBarry Smith     }
502efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
503efd51863SBarry Smith     if (flg) {
504efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
505efd51863SBarry Smith     }
506a8054027SBarry Smith 
50785385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
50885385478SLisandro Dalcin     if (flg) {
50985385478SLisandro Dalcin       switch (indx) {
5107f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5117f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
51285385478SLisandro Dalcin       }
51385385478SLisandro Dalcin     }
51485385478SLisandro Dalcin 
515acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
516186905e3SBarry Smith 
51785385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
51885385478SLisandro Dalcin 
519acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
520186905e3SBarry Smith 
521fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
522fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
523fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
524fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
525fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
526fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
527fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
528186905e3SBarry Smith 
52990d69ab7SBarry Smith     flg  = PETSC_FALSE;
530acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
531a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
532eabae89aSBarry Smith 
533a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
534e8105e01SRichard Katz     if (flg) {
535649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
536649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
537e8105e01SRichard Katz     }
538eabae89aSBarry Smith 
539b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
540b271bb04SBarry Smith     if (flg) {
541b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
542b271bb04SBarry Smith     }
543b271bb04SBarry Smith 
544a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
545eabae89aSBarry Smith     if (flg) {
546649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
547f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
548e8105e01SRichard Katz     }
549eabae89aSBarry Smith 
550a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
551eabae89aSBarry Smith     if (flg) {
552649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
553649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
554eabae89aSBarry Smith     }
555eabae89aSBarry Smith 
5565180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
5575180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
5585180491cSLisandro Dalcin 
55990d69ab7SBarry Smith     flg  = PETSC_FALSE;
560acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
561a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
56290d69ab7SBarry Smith     flg  = PETSC_FALSE;
563acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
564a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
56590d69ab7SBarry Smith     flg  = PETSC_FALSE;
566acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
567a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
56890d69ab7SBarry Smith     flg  = PETSC_FALSE;
569acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
570a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
57190d69ab7SBarry Smith     flg  = PETSC_FALSE;
572acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
573b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
574e24b481bSBarry Smith 
57590d69ab7SBarry Smith     flg  = PETSC_FALSE;
576acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
5774b27c08aSLois Curfman McInnes     if (flg) {
5786cab3a1bSJed Brown       void *functx;
5796cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
5806cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
581ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
5829b94acceSBarry Smith     }
583639f9d9dSBarry Smith 
584aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
585aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
586acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
587a8248277SBarry Smith     if (flg && mf_operator) {
588a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
589a8248277SBarry Smith       mf = PETSC_TRUE;
590a8248277SBarry Smith     }
591aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
592acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
593aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
594aa3661deSLisandro Dalcin     mf_version = 1;
595aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
596aa3661deSLisandro Dalcin 
597d28543b3SPeter Brune 
59889b92e6fSPeter Brune     /* GS Options */
59989b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
60089b92e6fSPeter Brune 
601ea630c6eSPeter Brune     /* line search options */
602ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_alpha","Constant function norm must decrease by","None",snes->ls_alpha,&snes->ls_alpha,0);CHKERRQ(ierr);
603ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_maxstep","Step must be less than","None",snes->maxstep,&snes->maxstep,0);CHKERRQ(ierr);
604ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_steptol","Minimum lambda allowed","None",snes->steptol,&snes->steptol,0);CHKERRQ(ierr);
605ea630c6eSPeter Brune     ierr = PetscOptionsReal("-snes_ls_damping","Damping parameter","SNES",snes->damping,&snes->damping,&flg);CHKERRQ(ierr);
606af60355fSPeter Brune     ierr = PetscOptionsInt("-snes_ls_it"      ,"Line search iterations","SNES",snes->ls_its,&snes->ls_its,&flg);CHKERRQ(ierr);
607ea630c6eSPeter Brune     ierr = PetscOptionsBool("-snes_ls_monitor","Print progress of line searches","SNESLineSearchSetMonitor",snes->ls_monitor ? PETSC_TRUE : PETSC_FALSE,&flg,&set);CHKERRQ(ierr);
608ea630c6eSPeter Brune     if (set) {ierr = SNESLineSearchSetMonitor(snes,flg);CHKERRQ(ierr);}
60915f5eeeaSPeter Brune     ierr = PetscOptionsEnum("-snes_ls","Line search used","SNESLineSearchSet",SNESLineSearchTypes,(PetscEnum)snes->ls_type,(PetscEnum*)&indx,&flg);CHKERRQ(ierr);
61015f5eeeaSPeter Brune     if (flg) {
611ea630c6eSPeter Brune       ierr = SNESLineSearchSetType(snes,(SNESLineSearchType)indx);CHKERRQ(ierr);
61215f5eeeaSPeter Brune     }
6138e3fc8c0SJed Brown     flg = snes->ops->precheckstep == SNESLineSearchPreCheckPicard ? PETSC_TRUE : PETSC_FALSE;
6148e3fc8c0SJed Brown     ierr = PetscOptionsBool("-snes_ls_precheck_picard","Use a correction that sometimes improves convergence of Picard iteration","SNESLineSearchPreCheckPicard",flg,&flg,&set);CHKERRQ(ierr);
6158e3fc8c0SJed Brown     if (set) {
6168e3fc8c0SJed Brown       if (flg) {
6178e3fc8c0SJed Brown         snes->precheck_picard_angle = 10.; /* correction only active if angle is less than 10 degrees */
6188e3fc8c0SJed Brown         ierr = PetscOptionsReal("-snes_ls_precheck_picard_angle","Maximum angle at which to activate the correction","none",snes->precheck_picard_angle,&snes->precheck_picard_angle,PETSC_NULL);CHKERRQ(ierr);
6198e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,SNESLineSearchPreCheckPicard,&snes->precheck_picard_angle);CHKERRQ(ierr);
6208e3fc8c0SJed Brown       } else {
6218e3fc8c0SJed Brown         ierr = SNESLineSearchSetPreCheck(snes,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
6228e3fc8c0SJed Brown       }
6238e3fc8c0SJed Brown     }
6248e3fc8c0SJed Brown 
62576b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
62676b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
62776b2cf59SMatthew Knepley     }
62876b2cf59SMatthew Knepley 
629e7788613SBarry Smith     if (snes->ops->setfromoptions) {
630e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
631639f9d9dSBarry Smith     }
6325d973c19SBarry Smith 
6335d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6345d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
635b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6364bbc92c1SBarry Smith 
637aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6381cee3971SBarry Smith 
6391cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
640aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
641aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
64285385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
64393993e2dSLois Curfman McInnes 
6449e764e56SPeter Brune   if (!snes->linesearch) {
6459e764e56SPeter Brune     ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6469e764e56SPeter Brune   }
6479e764e56SPeter Brune   ierr = PetscLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6489e764e56SPeter Brune 
64951e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
65051e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
65151e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
65251e86f29SPeter Brune   if (pcset && (!snes->pc)) {
65351e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
65451e86f29SPeter Brune   }
6554a0c5b0cSMatthew G Knepley   if (snes->pc) {
656fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
657fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
6584a0c5b0cSMatthew G Knepley     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
6594a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6604a0c5b0cSMatthew G Knepley   }
6613a40ed3dSBarry Smith   PetscFunctionReturn(0);
6629b94acceSBarry Smith }
6639b94acceSBarry Smith 
664d25893d9SBarry Smith #undef __FUNCT__
665d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
666d25893d9SBarry Smith /*@
667d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
668d25893d9SBarry Smith    the nonlinear solvers.
669d25893d9SBarry Smith 
670d25893d9SBarry Smith    Logically Collective on SNES
671d25893d9SBarry Smith 
672d25893d9SBarry Smith    Input Parameters:
673d25893d9SBarry Smith +  snes - the SNES context
674d25893d9SBarry Smith .  compute - function to compute the context
675d25893d9SBarry Smith -  destroy - function to destroy the context
676d25893d9SBarry Smith 
677d25893d9SBarry Smith    Level: intermediate
678d25893d9SBarry Smith 
679d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
680d25893d9SBarry Smith 
681d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
682d25893d9SBarry Smith @*/
683d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
684d25893d9SBarry Smith {
685d25893d9SBarry Smith   PetscFunctionBegin;
686d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
687d25893d9SBarry Smith   snes->ops->usercompute = compute;
688d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
689d25893d9SBarry Smith   PetscFunctionReturn(0);
690d25893d9SBarry Smith }
691a847f771SSatish Balay 
6924a2ae208SSatish Balay #undef __FUNCT__
6934a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
694b07ff414SBarry Smith /*@
6959b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
6969b94acceSBarry Smith    the nonlinear solvers.
6979b94acceSBarry Smith 
6983f9fe445SBarry Smith    Logically Collective on SNES
699fee21e36SBarry Smith 
700c7afd0dbSLois Curfman McInnes    Input Parameters:
701c7afd0dbSLois Curfman McInnes +  snes - the SNES context
702c7afd0dbSLois Curfman McInnes -  usrP - optional user context
703c7afd0dbSLois Curfman McInnes 
70436851e7fSLois Curfman McInnes    Level: intermediate
70536851e7fSLois Curfman McInnes 
7069b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7079b94acceSBarry Smith 
708d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
7099b94acceSBarry Smith @*/
7107087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7119b94acceSBarry Smith {
7121b2093e4SBarry Smith   PetscErrorCode ierr;
713b07ff414SBarry Smith   KSP            ksp;
7141b2093e4SBarry Smith 
7153a40ed3dSBarry Smith   PetscFunctionBegin;
7160700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
717b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
718b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7199b94acceSBarry Smith   snes->user = usrP;
7203a40ed3dSBarry Smith   PetscFunctionReturn(0);
7219b94acceSBarry Smith }
72274679c65SBarry Smith 
7234a2ae208SSatish Balay #undef __FUNCT__
7244a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
725b07ff414SBarry Smith /*@
7269b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7279b94acceSBarry Smith    nonlinear solvers.
7289b94acceSBarry Smith 
729c7afd0dbSLois Curfman McInnes    Not Collective
730c7afd0dbSLois Curfman McInnes 
7319b94acceSBarry Smith    Input Parameter:
7329b94acceSBarry Smith .  snes - SNES context
7339b94acceSBarry Smith 
7349b94acceSBarry Smith    Output Parameter:
7359b94acceSBarry Smith .  usrP - user context
7369b94acceSBarry Smith 
73736851e7fSLois Curfman McInnes    Level: intermediate
73836851e7fSLois Curfman McInnes 
7399b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7409b94acceSBarry Smith 
7419b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7429b94acceSBarry Smith @*/
743e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7449b94acceSBarry Smith {
7453a40ed3dSBarry Smith   PetscFunctionBegin;
7460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
747e71120c6SJed Brown   *(void**)usrP = snes->user;
7483a40ed3dSBarry Smith   PetscFunctionReturn(0);
7499b94acceSBarry Smith }
75074679c65SBarry Smith 
7514a2ae208SSatish Balay #undef __FUNCT__
7524a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7539b94acceSBarry Smith /*@
754c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
755c8228a4eSBarry Smith    at this time.
7569b94acceSBarry Smith 
757c7afd0dbSLois Curfman McInnes    Not Collective
758c7afd0dbSLois Curfman McInnes 
7599b94acceSBarry Smith    Input Parameter:
7609b94acceSBarry Smith .  snes - SNES context
7619b94acceSBarry Smith 
7629b94acceSBarry Smith    Output Parameter:
7639b94acceSBarry Smith .  iter - iteration number
7649b94acceSBarry Smith 
765c8228a4eSBarry Smith    Notes:
766c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
767c8228a4eSBarry Smith 
768c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
76908405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
77008405cd6SLois Curfman McInnes .vb
77108405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
77208405cd6SLois Curfman McInnes       if (!(it % 2)) {
77308405cd6SLois Curfman McInnes         [compute Jacobian here]
77408405cd6SLois Curfman McInnes       }
77508405cd6SLois Curfman McInnes .ve
776c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
77708405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
778c8228a4eSBarry Smith 
77936851e7fSLois Curfman McInnes    Level: intermediate
78036851e7fSLois Curfman McInnes 
7812b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
7822b668275SBarry Smith 
783b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
7849b94acceSBarry Smith @*/
7857087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
7869b94acceSBarry Smith {
7873a40ed3dSBarry Smith   PetscFunctionBegin;
7880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
7894482741eSBarry Smith   PetscValidIntPointer(iter,2);
7909b94acceSBarry Smith   *iter = snes->iter;
7913a40ed3dSBarry Smith   PetscFunctionReturn(0);
7929b94acceSBarry Smith }
79374679c65SBarry Smith 
7944a2ae208SSatish Balay #undef __FUNCT__
795360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
796360c497dSPeter Brune /*@
797360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
798360c497dSPeter Brune 
799360c497dSPeter Brune    Not Collective
800360c497dSPeter Brune 
801360c497dSPeter Brune    Input Parameter:
802360c497dSPeter Brune .  snes - SNES context
803360c497dSPeter Brune .  iter - iteration number
804360c497dSPeter Brune 
805360c497dSPeter Brune    Level: developer
806360c497dSPeter Brune 
807360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
808360c497dSPeter Brune 
809360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
810360c497dSPeter Brune @*/
811360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
812360c497dSPeter Brune {
813360c497dSPeter Brune   PetscErrorCode ierr;
814360c497dSPeter Brune 
815360c497dSPeter Brune   PetscFunctionBegin;
816360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
817360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
818360c497dSPeter Brune   snes->iter = iter;
819360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
820360c497dSPeter Brune   PetscFunctionReturn(0);
821360c497dSPeter Brune }
822360c497dSPeter Brune 
823360c497dSPeter Brune #undef __FUNCT__
8244a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8259b94acceSBarry Smith /*@
8269b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8279b94acceSBarry Smith    with SNESSSetFunction().
8289b94acceSBarry Smith 
829c7afd0dbSLois Curfman McInnes    Collective on SNES
830c7afd0dbSLois Curfman McInnes 
8319b94acceSBarry Smith    Input Parameter:
8329b94acceSBarry Smith .  snes - SNES context
8339b94acceSBarry Smith 
8349b94acceSBarry Smith    Output Parameter:
8359b94acceSBarry Smith .  fnorm - 2-norm of function
8369b94acceSBarry Smith 
83736851e7fSLois Curfman McInnes    Level: intermediate
83836851e7fSLois Curfman McInnes 
8399b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
840a86d99e1SLois Curfman McInnes 
841b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8429b94acceSBarry Smith @*/
8437087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8449b94acceSBarry Smith {
8453a40ed3dSBarry Smith   PetscFunctionBegin;
8460700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8474482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8489b94acceSBarry Smith   *fnorm = snes->norm;
8493a40ed3dSBarry Smith   PetscFunctionReturn(0);
8509b94acceSBarry Smith }
85174679c65SBarry Smith 
852360c497dSPeter Brune 
853360c497dSPeter Brune #undef __FUNCT__
854360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
855360c497dSPeter Brune /*@
856360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
857360c497dSPeter Brune 
858360c497dSPeter Brune    Collective on SNES
859360c497dSPeter Brune 
860360c497dSPeter Brune    Input Parameter:
861360c497dSPeter Brune .  snes - SNES context
862360c497dSPeter Brune .  fnorm - 2-norm of function
863360c497dSPeter Brune 
864360c497dSPeter Brune    Level: developer
865360c497dSPeter Brune 
866360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
867360c497dSPeter Brune 
868360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
869360c497dSPeter Brune @*/
870360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
871360c497dSPeter Brune {
872360c497dSPeter Brune 
873360c497dSPeter Brune   PetscErrorCode ierr;
874360c497dSPeter Brune 
875360c497dSPeter Brune   PetscFunctionBegin;
876360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
877360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
878360c497dSPeter Brune   snes->norm = fnorm;
879360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
880360c497dSPeter Brune   PetscFunctionReturn(0);
881360c497dSPeter Brune }
882360c497dSPeter Brune 
8834a2ae208SSatish Balay #undef __FUNCT__
884b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
8859b94acceSBarry Smith /*@
886b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
8879b94acceSBarry Smith    attempted by the nonlinear solver.
8889b94acceSBarry Smith 
889c7afd0dbSLois Curfman McInnes    Not Collective
890c7afd0dbSLois Curfman McInnes 
8919b94acceSBarry Smith    Input Parameter:
8929b94acceSBarry Smith .  snes - SNES context
8939b94acceSBarry Smith 
8949b94acceSBarry Smith    Output Parameter:
8959b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
8969b94acceSBarry Smith 
897c96a6f78SLois Curfman McInnes    Notes:
898c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
899c96a6f78SLois Curfman McInnes 
90036851e7fSLois Curfman McInnes    Level: intermediate
90136851e7fSLois Curfman McInnes 
9029b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
90358ebbce7SBarry Smith 
904e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
90558ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9069b94acceSBarry Smith @*/
9077087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9089b94acceSBarry Smith {
9093a40ed3dSBarry Smith   PetscFunctionBegin;
9100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9114482741eSBarry Smith   PetscValidIntPointer(nfails,2);
91250ffb88aSMatthew Knepley   *nfails = snes->numFailures;
91350ffb88aSMatthew Knepley   PetscFunctionReturn(0);
91450ffb88aSMatthew Knepley }
91550ffb88aSMatthew Knepley 
91650ffb88aSMatthew Knepley #undef __FUNCT__
917b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
91850ffb88aSMatthew Knepley /*@
919b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
92050ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
92150ffb88aSMatthew Knepley 
92250ffb88aSMatthew Knepley    Not Collective
92350ffb88aSMatthew Knepley 
92450ffb88aSMatthew Knepley    Input Parameters:
92550ffb88aSMatthew Knepley +  snes     - SNES context
92650ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
92750ffb88aSMatthew Knepley 
92850ffb88aSMatthew Knepley    Level: intermediate
92950ffb88aSMatthew Knepley 
93050ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
93158ebbce7SBarry Smith 
932e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
93358ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
93450ffb88aSMatthew Knepley @*/
9357087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
93650ffb88aSMatthew Knepley {
93750ffb88aSMatthew Knepley   PetscFunctionBegin;
9380700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
93950ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
94050ffb88aSMatthew Knepley   PetscFunctionReturn(0);
94150ffb88aSMatthew Knepley }
94250ffb88aSMatthew Knepley 
94350ffb88aSMatthew Knepley #undef __FUNCT__
944b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
94550ffb88aSMatthew Knepley /*@
946b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
94750ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
94850ffb88aSMatthew Knepley 
94950ffb88aSMatthew Knepley    Not Collective
95050ffb88aSMatthew Knepley 
95150ffb88aSMatthew Knepley    Input Parameter:
95250ffb88aSMatthew Knepley .  snes     - SNES context
95350ffb88aSMatthew Knepley 
95450ffb88aSMatthew Knepley    Output Parameter:
95550ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
95650ffb88aSMatthew Knepley 
95750ffb88aSMatthew Knepley    Level: intermediate
95850ffb88aSMatthew Knepley 
95950ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
96058ebbce7SBarry Smith 
961e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
96258ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
96358ebbce7SBarry Smith 
96450ffb88aSMatthew Knepley @*/
9657087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
96650ffb88aSMatthew Knepley {
96750ffb88aSMatthew Knepley   PetscFunctionBegin;
9680700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9694482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
97050ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
9713a40ed3dSBarry Smith   PetscFunctionReturn(0);
9729b94acceSBarry Smith }
973a847f771SSatish Balay 
9744a2ae208SSatish Balay #undef __FUNCT__
9752541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
9762541af92SBarry Smith /*@
9772541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
9782541af92SBarry Smith      done by SNES.
9792541af92SBarry Smith 
9802541af92SBarry Smith    Not Collective
9812541af92SBarry Smith 
9822541af92SBarry Smith    Input Parameter:
9832541af92SBarry Smith .  snes     - SNES context
9842541af92SBarry Smith 
9852541af92SBarry Smith    Output Parameter:
9862541af92SBarry Smith .  nfuncs - number of evaluations
9872541af92SBarry Smith 
9882541af92SBarry Smith    Level: intermediate
9892541af92SBarry Smith 
9902541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
99158ebbce7SBarry Smith 
992e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
9932541af92SBarry Smith @*/
9947087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
9952541af92SBarry Smith {
9962541af92SBarry Smith   PetscFunctionBegin;
9970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9982541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
9992541af92SBarry Smith   *nfuncs = snes->nfuncs;
10002541af92SBarry Smith   PetscFunctionReturn(0);
10012541af92SBarry Smith }
10022541af92SBarry Smith 
10032541af92SBarry Smith #undef __FUNCT__
10043d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10053d4c4710SBarry Smith /*@
10063d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10073d4c4710SBarry Smith    linear solvers.
10083d4c4710SBarry Smith 
10093d4c4710SBarry Smith    Not Collective
10103d4c4710SBarry Smith 
10113d4c4710SBarry Smith    Input Parameter:
10123d4c4710SBarry Smith .  snes - SNES context
10133d4c4710SBarry Smith 
10143d4c4710SBarry Smith    Output Parameter:
10153d4c4710SBarry Smith .  nfails - number of failed solves
10163d4c4710SBarry Smith 
10173d4c4710SBarry Smith    Notes:
10183d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10193d4c4710SBarry Smith 
10203d4c4710SBarry Smith    Level: intermediate
10213d4c4710SBarry Smith 
10223d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
102358ebbce7SBarry Smith 
1024e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10253d4c4710SBarry Smith @*/
10267087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10273d4c4710SBarry Smith {
10283d4c4710SBarry Smith   PetscFunctionBegin;
10290700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10303d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10313d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10323d4c4710SBarry Smith   PetscFunctionReturn(0);
10333d4c4710SBarry Smith }
10343d4c4710SBarry Smith 
10353d4c4710SBarry Smith #undef __FUNCT__
10363d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10373d4c4710SBarry Smith /*@
10383d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10393d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10403d4c4710SBarry Smith 
10413f9fe445SBarry Smith    Logically Collective on SNES
10423d4c4710SBarry Smith 
10433d4c4710SBarry Smith    Input Parameters:
10443d4c4710SBarry Smith +  snes     - SNES context
10453d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10463d4c4710SBarry Smith 
10473d4c4710SBarry Smith    Level: intermediate
10483d4c4710SBarry Smith 
1049a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10503d4c4710SBarry Smith 
10513d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10523d4c4710SBarry Smith 
105358ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10543d4c4710SBarry Smith @*/
10557087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10563d4c4710SBarry Smith {
10573d4c4710SBarry Smith   PetscFunctionBegin;
10580700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1059c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10603d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10613d4c4710SBarry Smith   PetscFunctionReturn(0);
10623d4c4710SBarry Smith }
10633d4c4710SBarry Smith 
10643d4c4710SBarry Smith #undef __FUNCT__
10653d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
10663d4c4710SBarry Smith /*@
10673d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
10683d4c4710SBarry Smith      are allowed before SNES terminates
10693d4c4710SBarry Smith 
10703d4c4710SBarry Smith    Not Collective
10713d4c4710SBarry Smith 
10723d4c4710SBarry Smith    Input Parameter:
10733d4c4710SBarry Smith .  snes     - SNES context
10743d4c4710SBarry Smith 
10753d4c4710SBarry Smith    Output Parameter:
10763d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
10773d4c4710SBarry Smith 
10783d4c4710SBarry Smith    Level: intermediate
10793d4c4710SBarry Smith 
10803d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
10813d4c4710SBarry Smith 
10823d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
10833d4c4710SBarry Smith 
1084e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
10853d4c4710SBarry Smith @*/
10867087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
10873d4c4710SBarry Smith {
10883d4c4710SBarry Smith   PetscFunctionBegin;
10890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10903d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
10913d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
10923d4c4710SBarry Smith   PetscFunctionReturn(0);
10933d4c4710SBarry Smith }
10943d4c4710SBarry Smith 
10953d4c4710SBarry Smith #undef __FUNCT__
1096b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1097c96a6f78SLois Curfman McInnes /*@
1098b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1099c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1100c96a6f78SLois Curfman McInnes 
1101c7afd0dbSLois Curfman McInnes    Not Collective
1102c7afd0dbSLois Curfman McInnes 
1103c96a6f78SLois Curfman McInnes    Input Parameter:
1104c96a6f78SLois Curfman McInnes .  snes - SNES context
1105c96a6f78SLois Curfman McInnes 
1106c96a6f78SLois Curfman McInnes    Output Parameter:
1107c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1108c96a6f78SLois Curfman McInnes 
1109c96a6f78SLois Curfman McInnes    Notes:
1110c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1111c96a6f78SLois Curfman McInnes 
111236851e7fSLois Curfman McInnes    Level: intermediate
111336851e7fSLois Curfman McInnes 
1114c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11152b668275SBarry Smith 
11168c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1117c96a6f78SLois Curfman McInnes @*/
11187087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1119c96a6f78SLois Curfman McInnes {
11203a40ed3dSBarry Smith   PetscFunctionBegin;
11210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11224482741eSBarry Smith   PetscValidIntPointer(lits,2);
1123c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1125c96a6f78SLois Curfman McInnes }
1126c96a6f78SLois Curfman McInnes 
11274a2ae208SSatish Balay #undef __FUNCT__
112894b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
112952baeb72SSatish Balay /*@
113094b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11319b94acceSBarry Smith 
113294b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1133c7afd0dbSLois Curfman McInnes 
11349b94acceSBarry Smith    Input Parameter:
11359b94acceSBarry Smith .  snes - the SNES context
11369b94acceSBarry Smith 
11379b94acceSBarry Smith    Output Parameter:
113894b7f48cSBarry Smith .  ksp - the KSP context
11399b94acceSBarry Smith 
11409b94acceSBarry Smith    Notes:
114194b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11429b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11432999313aSBarry Smith    PC contexts as well.
11449b94acceSBarry Smith 
114536851e7fSLois Curfman McInnes    Level: beginner
114636851e7fSLois Curfman McInnes 
114794b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11489b94acceSBarry Smith 
11492999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11509b94acceSBarry Smith @*/
11517087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11529b94acceSBarry Smith {
11531cee3971SBarry Smith   PetscErrorCode ierr;
11541cee3971SBarry Smith 
11553a40ed3dSBarry Smith   PetscFunctionBegin;
11560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11574482741eSBarry Smith   PetscValidPointer(ksp,2);
11581cee3971SBarry Smith 
11591cee3971SBarry Smith   if (!snes->ksp) {
11601cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11611cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11621cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11631cee3971SBarry Smith   }
116494b7f48cSBarry Smith   *ksp = snes->ksp;
11653a40ed3dSBarry Smith   PetscFunctionReturn(0);
11669b94acceSBarry Smith }
116782bf6240SBarry Smith 
11684a2ae208SSatish Balay #undef __FUNCT__
11692999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
11702999313aSBarry Smith /*@
11712999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
11722999313aSBarry Smith 
11732999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
11742999313aSBarry Smith 
11752999313aSBarry Smith    Input Parameters:
11762999313aSBarry Smith +  snes - the SNES context
11772999313aSBarry Smith -  ksp - the KSP context
11782999313aSBarry Smith 
11792999313aSBarry Smith    Notes:
11802999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
11812999313aSBarry Smith    so this routine is rarely needed.
11822999313aSBarry Smith 
11832999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
11842999313aSBarry Smith    decreased by one.
11852999313aSBarry Smith 
11862999313aSBarry Smith    Level: developer
11872999313aSBarry Smith 
11882999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11892999313aSBarry Smith 
11902999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11912999313aSBarry Smith @*/
11927087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
11932999313aSBarry Smith {
11942999313aSBarry Smith   PetscErrorCode ierr;
11952999313aSBarry Smith 
11962999313aSBarry Smith   PetscFunctionBegin;
11970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11980700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
11992999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12007dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1201906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12022999313aSBarry Smith   snes->ksp = ksp;
12032999313aSBarry Smith   PetscFunctionReturn(0);
12042999313aSBarry Smith }
12052999313aSBarry Smith 
12067adad957SLisandro Dalcin #if 0
12072999313aSBarry Smith #undef __FUNCT__
12084a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12096849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1210e24b481bSBarry Smith {
1211e24b481bSBarry Smith   PetscFunctionBegin;
1212e24b481bSBarry Smith   PetscFunctionReturn(0);
1213e24b481bSBarry Smith }
12147adad957SLisandro Dalcin #endif
1215e24b481bSBarry Smith 
12169b94acceSBarry Smith /* -----------------------------------------------------------*/
12174a2ae208SSatish Balay #undef __FUNCT__
12184a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
121952baeb72SSatish Balay /*@
12209b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12219b94acceSBarry Smith 
1222c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1223c7afd0dbSLois Curfman McInnes 
1224c7afd0dbSLois Curfman McInnes    Input Parameters:
1225906ed7ccSBarry Smith .  comm - MPI communicator
12269b94acceSBarry Smith 
12279b94acceSBarry Smith    Output Parameter:
12289b94acceSBarry Smith .  outsnes - the new SNES context
12299b94acceSBarry Smith 
1230c7afd0dbSLois Curfman McInnes    Options Database Keys:
1231c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1232c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1233c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1234c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1235c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1236c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1237c1f60f51SBarry Smith 
123836851e7fSLois Curfman McInnes    Level: beginner
123936851e7fSLois Curfman McInnes 
12409b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12419b94acceSBarry Smith 
1242a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1243a8054027SBarry Smith 
12449b94acceSBarry Smith @*/
12457087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12469b94acceSBarry Smith {
1247dfbe8321SBarry Smith   PetscErrorCode      ierr;
12489b94acceSBarry Smith   SNES                snes;
1249fa9f3622SBarry Smith   SNESKSPEW           *kctx;
125037fcc0dbSBarry Smith 
12513a40ed3dSBarry Smith   PetscFunctionBegin;
1252ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12538ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12548ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12558ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12568ba1e511SMatthew Knepley #endif
12578ba1e511SMatthew Knepley 
12583194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12597adad957SLisandro Dalcin 
126085385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12612c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
12629b94acceSBarry Smith   snes->max_its           = 50;
12639750a799SBarry Smith   snes->max_funcs	  = 10000;
12649b94acceSBarry Smith   snes->norm		  = 0.0;
1265b4874afaSBarry Smith   snes->rtol		  = 1.e-8;
1266b4874afaSBarry Smith   snes->ttol              = 0.0;
126770441072SBarry Smith   snes->abstol		  = 1.e-50;
12689b94acceSBarry Smith   snes->xtol		  = 1.e-8;
12694b27c08aSLois Curfman McInnes   snes->deltatol	  = 1.e-12;
12709b94acceSBarry Smith   snes->nfuncs            = 0;
127150ffb88aSMatthew Knepley   snes->numFailures       = 0;
127250ffb88aSMatthew Knepley   snes->maxFailures       = 1;
12737a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1274e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1275a8054027SBarry Smith   snes->lagpreconditioner = 1;
1276639f9d9dSBarry Smith   snes->numbermonitors    = 0;
12779b94acceSBarry Smith   snes->data              = 0;
12784dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1279186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
12806f24a144SLois Curfman McInnes   snes->nwork             = 0;
128158c9b817SLisandro Dalcin   snes->work              = 0;
128258c9b817SLisandro Dalcin   snes->nvwork            = 0;
128358c9b817SLisandro Dalcin   snes->vwork             = 0;
1284758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1285758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1286758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1287758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1288758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1289184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
129089b92e6fSPeter Brune   snes->gssweeps          = 1;
12919b94acceSBarry Smith 
1292ea630c6eSPeter Brune   /* initialize the line search options */
12939e764e56SPeter Brune   snes->linesearch        = PETSC_NULL;
1294ea630c6eSPeter Brune   snes->ls_type           = SNES_LS_BASIC;
1295af60355fSPeter Brune   snes->ls_its            = 1;
1296ea630c6eSPeter Brune   snes->damping           = 1.0;
1297ea630c6eSPeter Brune   snes->maxstep           = 1e8;
1298ea630c6eSPeter Brune   snes->steptol           = 1e-12;
1299ea630c6eSPeter Brune   snes->ls_alpha          = 1e-4;
1300ea630c6eSPeter Brune   snes->ls_monitor        = PETSC_NULL;
1301ea630c6eSPeter Brune 
1302ea630c6eSPeter Brune   snes->ops->linesearch   = PETSC_NULL;
1303ea630c6eSPeter Brune   snes->precheck          = PETSC_NULL;
1304ea630c6eSPeter Brune   snes->ops->precheckstep = PETSC_NULL;
1305ea630c6eSPeter Brune   snes->postcheck         = PETSC_NULL;
1306ea630c6eSPeter Brune   snes->ops->postcheckstep= PETSC_NULL;
1307ea630c6eSPeter Brune 
13083d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13093d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13103d4c4710SBarry Smith 
13119b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
131238f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13139b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13149b94acceSBarry Smith   kctx->version     = 2;
13159b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13169b94acceSBarry Smith                              this was too large for some test cases */
131775567043SBarry Smith   kctx->rtol_last   = 0.0;
13189b94acceSBarry Smith   kctx->rtol_max    = .9;
13199b94acceSBarry Smith   kctx->gamma       = 1.0;
132062d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
132171f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13229b94acceSBarry Smith   kctx->threshold   = .1;
132375567043SBarry Smith   kctx->lresid_last = 0.0;
132475567043SBarry Smith   kctx->norm_last   = 0.0;
13259b94acceSBarry Smith 
13269b94acceSBarry Smith   *outsnes = snes;
13273a40ed3dSBarry Smith   PetscFunctionReturn(0);
13289b94acceSBarry Smith }
13299b94acceSBarry Smith 
13304a2ae208SSatish Balay #undef __FUNCT__
13314a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13329b94acceSBarry Smith /*@C
13339b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13349b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13359b94acceSBarry Smith    equations.
13369b94acceSBarry Smith 
13373f9fe445SBarry Smith    Logically Collective on SNES
1338fee21e36SBarry Smith 
1339c7afd0dbSLois Curfman McInnes    Input Parameters:
1340c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1341c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1342de044059SHong Zhang .  func - function evaluation routine
1343c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1344c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13459b94acceSBarry Smith 
1346c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13478d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1348c7afd0dbSLois Curfman McInnes 
1349313e4042SLois Curfman McInnes .  f - function vector
1350c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13519b94acceSBarry Smith 
13529b94acceSBarry Smith    Notes:
13539b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13549b94acceSBarry Smith $      f'(x) x = -f(x),
1355c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13569b94acceSBarry Smith 
135736851e7fSLois Curfman McInnes    Level: beginner
135836851e7fSLois Curfman McInnes 
13599b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13609b94acceSBarry Smith 
13618b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13629b94acceSBarry Smith @*/
13637087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13649b94acceSBarry Smith {
136585385478SLisandro Dalcin   PetscErrorCode ierr;
13666cab3a1bSJed Brown   DM             dm;
13676cab3a1bSJed Brown 
13683a40ed3dSBarry Smith   PetscFunctionBegin;
13690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1370d2a683ecSLisandro Dalcin   if (r) {
1371d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1372d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
137385385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
13746bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
137585385478SLisandro Dalcin     snes->vec_func = r;
1376d2a683ecSLisandro Dalcin   }
13776cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
13786cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
13793a40ed3dSBarry Smith   PetscFunctionReturn(0);
13809b94acceSBarry Smith }
13819b94acceSBarry Smith 
1382646217ecSPeter Brune 
1383646217ecSPeter Brune #undef __FUNCT__
1384646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1385c79ef259SPeter Brune /*@C
1386c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1387c79ef259SPeter Brune    use with composed nonlinear solvers.
1388c79ef259SPeter Brune 
1389c79ef259SPeter Brune    Input Parameters:
1390c79ef259SPeter Brune +  snes   - the SNES context
1391c79ef259SPeter Brune .  gsfunc - function evaluation routine
1392c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1393c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1394c79ef259SPeter Brune 
1395c79ef259SPeter Brune    Calling sequence of func:
1396c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1397c79ef259SPeter Brune 
1398c79ef259SPeter Brune +  X   - solution vector
1399c79ef259SPeter Brune .  B   - RHS vector
1400d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1401c79ef259SPeter Brune 
1402c79ef259SPeter Brune    Notes:
1403c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1404c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1405c79ef259SPeter Brune 
1406d28543b3SPeter Brune    Level: intermediate
1407c79ef259SPeter Brune 
1408d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1409c79ef259SPeter Brune 
1410c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1411c79ef259SPeter Brune @*/
14126cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
14136cab3a1bSJed Brown {
14146cab3a1bSJed Brown   PetscErrorCode ierr;
14156cab3a1bSJed Brown   DM dm;
14166cab3a1bSJed Brown 
1417646217ecSPeter Brune   PetscFunctionBegin;
14186cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
14196cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14206cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1421646217ecSPeter Brune   PetscFunctionReturn(0);
1422646217ecSPeter Brune }
1423646217ecSPeter Brune 
1424d25893d9SBarry Smith #undef __FUNCT__
142589b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
142689b92e6fSPeter Brune /*@
142789b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
142889b92e6fSPeter Brune 
142989b92e6fSPeter Brune    Input Parameters:
143089b92e6fSPeter Brune +  snes   - the SNES context
143189b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
143289b92e6fSPeter Brune 
143389b92e6fSPeter Brune    Level: intermediate
143489b92e6fSPeter Brune 
143589b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
143689b92e6fSPeter Brune 
143789b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
143889b92e6fSPeter Brune @*/
143989b92e6fSPeter Brune 
144089b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
144189b92e6fSPeter Brune   PetscFunctionBegin;
144289b92e6fSPeter Brune   snes->gssweeps = sweeps;
144389b92e6fSPeter Brune   PetscFunctionReturn(0);
144489b92e6fSPeter Brune }
144589b92e6fSPeter Brune 
144689b92e6fSPeter Brune 
144789b92e6fSPeter Brune #undef __FUNCT__
144889b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
144989b92e6fSPeter Brune /*@
145089b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
145189b92e6fSPeter Brune 
145289b92e6fSPeter Brune    Input Parameters:
145389b92e6fSPeter Brune .  snes   - the SNES context
145489b92e6fSPeter Brune 
145589b92e6fSPeter Brune    Output Parameters:
145689b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
145789b92e6fSPeter Brune 
145889b92e6fSPeter Brune    Level: intermediate
145989b92e6fSPeter Brune 
146089b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
146189b92e6fSPeter Brune 
146289b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
146389b92e6fSPeter Brune @*/
146489b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
146589b92e6fSPeter Brune   PetscFunctionBegin;
146689b92e6fSPeter Brune   *sweeps = snes->gssweeps;
146789b92e6fSPeter Brune   PetscFunctionReturn(0);
146889b92e6fSPeter Brune }
146989b92e6fSPeter Brune 
147089b92e6fSPeter Brune #undef __FUNCT__
14718b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
14728b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
14738b0a5094SBarry Smith {
14748b0a5094SBarry Smith   PetscErrorCode ierr;
14756cab3a1bSJed Brown   void *functx,*jacctx;
14766cab3a1bSJed Brown 
14778b0a5094SBarry Smith   PetscFunctionBegin;
14786cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
14796cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
14808b0a5094SBarry Smith   /*  A(x)*x - b(x) */
14816cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
14826cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
14838b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14848b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
14858b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
14868b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
14878b0a5094SBarry Smith   PetscFunctionReturn(0);
14888b0a5094SBarry Smith }
14898b0a5094SBarry Smith 
14908b0a5094SBarry Smith #undef __FUNCT__
14918b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
14928b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
14938b0a5094SBarry Smith {
14948b0a5094SBarry Smith   PetscFunctionBegin;
14958b0a5094SBarry Smith   *flag = snes->matstruct;
14968b0a5094SBarry Smith   PetscFunctionReturn(0);
14978b0a5094SBarry Smith }
14988b0a5094SBarry Smith 
14998b0a5094SBarry Smith #undef __FUNCT__
15008b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
15018b0a5094SBarry Smith /*@C
15020d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
15038b0a5094SBarry Smith 
15048b0a5094SBarry Smith    Logically Collective on SNES
15058b0a5094SBarry Smith 
15068b0a5094SBarry Smith    Input Parameters:
15078b0a5094SBarry Smith +  snes - the SNES context
15088b0a5094SBarry Smith .  r - vector to store function value
15098b0a5094SBarry Smith .  func - function evaluation routine
15108b0a5094SBarry 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)
15118b0a5094SBarry Smith .  mat - matrix to store A
15128b0a5094SBarry Smith .  mfunc  - function to compute matrix value
15138b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
15148b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
15158b0a5094SBarry Smith 
15168b0a5094SBarry Smith    Calling sequence of func:
15178b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
15188b0a5094SBarry Smith 
15198b0a5094SBarry Smith +  f - function vector
15208b0a5094SBarry Smith -  ctx - optional user-defined function context
15218b0a5094SBarry Smith 
15228b0a5094SBarry Smith    Calling sequence of mfunc:
15238b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
15248b0a5094SBarry Smith 
15258b0a5094SBarry Smith +  x - input vector
15268b0a5094SBarry 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(),
15278b0a5094SBarry Smith           normally just pass mat in this location
15288b0a5094SBarry Smith .  mat - form A(x) matrix
15298b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
15308b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
15318b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
15328b0a5094SBarry Smith 
15338b0a5094SBarry Smith    Notes:
15348b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
15358b0a5094SBarry Smith 
15368b0a5094SBarry 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}
15378b0a5094SBarry 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.
15388b0a5094SBarry Smith 
15398b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
15408b0a5094SBarry Smith 
15410d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
15420d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
15438b0a5094SBarry Smith 
15448b0a5094SBarry 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
15458b0a5094SBarry 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
15468b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
15478b0a5094SBarry Smith 
15488b0a5094SBarry Smith    Level: beginner
15498b0a5094SBarry Smith 
15508b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
15518b0a5094SBarry Smith 
15520d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
15538b0a5094SBarry Smith @*/
15548b0a5094SBarry 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)
15558b0a5094SBarry Smith {
15568b0a5094SBarry Smith   PetscErrorCode ierr;
15578b0a5094SBarry Smith   PetscFunctionBegin;
15588b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15598b0a5094SBarry Smith   snes->ops->computepfunction = func;
15608b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
15618b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
15628b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
15638b0a5094SBarry Smith   PetscFunctionReturn(0);
15648b0a5094SBarry Smith }
15658b0a5094SBarry Smith 
15668b0a5094SBarry Smith #undef __FUNCT__
1567d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1568d25893d9SBarry Smith /*@C
1569d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1570d25893d9SBarry Smith 
1571d25893d9SBarry Smith    Logically Collective on SNES
1572d25893d9SBarry Smith 
1573d25893d9SBarry Smith    Input Parameters:
1574d25893d9SBarry Smith +  snes - the SNES context
1575d25893d9SBarry Smith .  func - function evaluation routine
1576d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1577d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1578d25893d9SBarry Smith 
1579d25893d9SBarry Smith    Calling sequence of func:
1580d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1581d25893d9SBarry Smith 
1582d25893d9SBarry Smith .  f - function vector
1583d25893d9SBarry Smith -  ctx - optional user-defined function context
1584d25893d9SBarry Smith 
1585d25893d9SBarry Smith    Level: intermediate
1586d25893d9SBarry Smith 
1587d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1588d25893d9SBarry Smith 
1589d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1590d25893d9SBarry Smith @*/
1591d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1592d25893d9SBarry Smith {
1593d25893d9SBarry Smith   PetscFunctionBegin;
1594d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1595d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1596d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1597d25893d9SBarry Smith   PetscFunctionReturn(0);
1598d25893d9SBarry Smith }
1599d25893d9SBarry Smith 
16003ab0aad5SBarry Smith /* --------------------------------------------------------------- */
16013ab0aad5SBarry Smith #undef __FUNCT__
16021096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
16031096aae1SMatthew Knepley /*@C
16041096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
16051096aae1SMatthew Knepley    it assumes a zero right hand side.
16061096aae1SMatthew Knepley 
16073f9fe445SBarry Smith    Logically Collective on SNES
16081096aae1SMatthew Knepley 
16091096aae1SMatthew Knepley    Input Parameter:
16101096aae1SMatthew Knepley .  snes - the SNES context
16111096aae1SMatthew Knepley 
16121096aae1SMatthew Knepley    Output Parameter:
1613bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
16141096aae1SMatthew Knepley 
16151096aae1SMatthew Knepley    Level: intermediate
16161096aae1SMatthew Knepley 
16171096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
16181096aae1SMatthew Knepley 
161985385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
16201096aae1SMatthew Knepley @*/
16217087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
16221096aae1SMatthew Knepley {
16231096aae1SMatthew Knepley   PetscFunctionBegin;
16240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16251096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
162685385478SLisandro Dalcin   *rhs = snes->vec_rhs;
16271096aae1SMatthew Knepley   PetscFunctionReturn(0);
16281096aae1SMatthew Knepley }
16291096aae1SMatthew Knepley 
16301096aae1SMatthew Knepley #undef __FUNCT__
16314a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
16329b94acceSBarry Smith /*@
163336851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
16349b94acceSBarry Smith                          SNESSetFunction().
16359b94acceSBarry Smith 
1636c7afd0dbSLois Curfman McInnes    Collective on SNES
1637c7afd0dbSLois Curfman McInnes 
16389b94acceSBarry Smith    Input Parameters:
1639c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1640c7afd0dbSLois Curfman McInnes -  x - input vector
16419b94acceSBarry Smith 
16429b94acceSBarry Smith    Output Parameter:
16433638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
16449b94acceSBarry Smith 
16451bffabb2SLois Curfman McInnes    Notes:
164636851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
164736851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
164836851e7fSLois Curfman McInnes    themselves.
164936851e7fSLois Curfman McInnes 
165036851e7fSLois Curfman McInnes    Level: developer
165136851e7fSLois Curfman McInnes 
16529b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
16539b94acceSBarry Smith 
1654a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
16559b94acceSBarry Smith @*/
16567087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
16579b94acceSBarry Smith {
1658dfbe8321SBarry Smith   PetscErrorCode ierr;
16596cab3a1bSJed Brown   DM             dm;
16606cab3a1bSJed Brown   SNESDM         sdm;
16619b94acceSBarry Smith 
16623a40ed3dSBarry Smith   PetscFunctionBegin;
16630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
16640700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
16650700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1666c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1667c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
16684ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1669184914b5SBarry Smith 
16706cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
16716cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1672d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16736cab3a1bSJed Brown   if (sdm->computefunction) {
1674d64ed03dSBarry Smith     PetscStackPush("SNES user function");
16756cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1676d64ed03dSBarry Smith     PetscStackPop;
167773250ac0SBarry Smith   } else if (snes->dm) {
1678644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1679c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1680c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1681644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
168285385478SLisandro Dalcin   if (snes->vec_rhs) {
168385385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
16843ab0aad5SBarry Smith   }
1685ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1686d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
16874ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
16883a40ed3dSBarry Smith   PetscFunctionReturn(0);
16899b94acceSBarry Smith }
16909b94acceSBarry Smith 
16914a2ae208SSatish Balay #undef __FUNCT__
1692646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1693c79ef259SPeter Brune /*@
1694c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1695c79ef259SPeter Brune                    SNESSetGS().
1696c79ef259SPeter Brune 
1697c79ef259SPeter Brune    Collective on SNES
1698c79ef259SPeter Brune 
1699c79ef259SPeter Brune    Input Parameters:
1700c79ef259SPeter Brune +  snes - the SNES context
1701c79ef259SPeter Brune .  x - input vector
1702c79ef259SPeter Brune -  b - rhs vector
1703c79ef259SPeter Brune 
1704c79ef259SPeter Brune    Output Parameter:
1705c79ef259SPeter Brune .  x - new solution vector
1706c79ef259SPeter Brune 
1707c79ef259SPeter Brune    Notes:
1708c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1709c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1710c79ef259SPeter Brune    themselves.
1711c79ef259SPeter Brune 
1712c79ef259SPeter Brune    Level: developer
1713c79ef259SPeter Brune 
1714c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1715c79ef259SPeter Brune 
1716c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1717c79ef259SPeter Brune @*/
1718646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1719646217ecSPeter Brune {
1720646217ecSPeter Brune   PetscErrorCode ierr;
172189b92e6fSPeter Brune   PetscInt i;
17226cab3a1bSJed Brown   DM dm;
17236cab3a1bSJed Brown   SNESDM sdm;
1724646217ecSPeter Brune 
1725646217ecSPeter Brune   PetscFunctionBegin;
1726646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1727646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1728646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1729646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1730646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
17314ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1732701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17336cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
17346cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
17356cab3a1bSJed Brown   if (sdm->computegs) {
173689b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1737646217ecSPeter Brune       PetscStackPush("SNES user GS");
17386cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1739646217ecSPeter Brune       PetscStackPop;
174089b92e6fSPeter Brune     }
1741646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1742701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
17434ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1744646217ecSPeter Brune   PetscFunctionReturn(0);
1745646217ecSPeter Brune }
1746646217ecSPeter Brune 
1747646217ecSPeter Brune 
1748646217ecSPeter Brune #undef __FUNCT__
17494a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
175062fef451SLois Curfman McInnes /*@
175162fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
175262fef451SLois Curfman McInnes    set with SNESSetJacobian().
175362fef451SLois Curfman McInnes 
1754c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1755c7afd0dbSLois Curfman McInnes 
175662fef451SLois Curfman McInnes    Input Parameters:
1757c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1758c7afd0dbSLois Curfman McInnes -  x - input vector
175962fef451SLois Curfman McInnes 
176062fef451SLois Curfman McInnes    Output Parameters:
1761c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
176262fef451SLois Curfman McInnes .  B - optional preconditioning matrix
17632b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1764fee21e36SBarry Smith 
1765e35cf81dSBarry Smith   Options Database Keys:
1766e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1767693365a8SJed Brown .    -snes_lag_jacobian <lag>
1768693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1769693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1770693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
17714c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1772c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1773c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1774c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1775c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1776c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
17774c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1778c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1779c01495d3SJed Brown 
1780e35cf81dSBarry Smith 
178162fef451SLois Curfman McInnes    Notes:
178262fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
178362fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
178462fef451SLois Curfman McInnes 
178594b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1786dc5a77f8SLois Curfman McInnes    flag parameter.
178762fef451SLois Curfman McInnes 
178836851e7fSLois Curfman McInnes    Level: developer
178936851e7fSLois Curfman McInnes 
179062fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
179162fef451SLois Curfman McInnes 
1792e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
179362fef451SLois Curfman McInnes @*/
17947087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
17959b94acceSBarry Smith {
1796dfbe8321SBarry Smith   PetscErrorCode ierr;
1797ace3abfcSBarry Smith   PetscBool      flag;
17986cab3a1bSJed Brown   DM             dm;
17996cab3a1bSJed Brown   SNESDM         sdm;
18003a40ed3dSBarry Smith 
18013a40ed3dSBarry Smith   PetscFunctionBegin;
18020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18030700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
18044482741eSBarry Smith   PetscValidPointer(flg,5);
1805c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
18064ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
18076cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18086cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18096cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1810ebd3b9afSBarry Smith 
1811ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1812ebd3b9afSBarry Smith 
1813fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1814fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1815fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1816fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1817e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1818e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1819ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1820ebd3b9afSBarry Smith     if (flag) {
1821ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1822ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1823ebd3b9afSBarry Smith     }
1824e35cf81dSBarry Smith     PetscFunctionReturn(0);
1825e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1826e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1827e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1828ebd3b9afSBarry Smith     ierr = PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1829ebd3b9afSBarry Smith     if (flag) {
1830ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1831ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1832ebd3b9afSBarry Smith     }
1833e35cf81dSBarry Smith     PetscFunctionReturn(0);
1834e35cf81dSBarry Smith   }
1835e35cf81dSBarry Smith 
1836c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1837e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1838d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
18396cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
1840d64ed03dSBarry Smith   PetscStackPop;
1841d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1842a8054027SBarry Smith 
18433b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
18443b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
18453b4f5425SBarry Smith     snes->lagpreconditioner = -1;
18463b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
1847a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1848a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
1849a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1850a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
1851a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
1852a8054027SBarry Smith   }
1853a8054027SBarry Smith 
18546d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
18550700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
18560700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
1857693365a8SJed Brown   {
1858693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1859693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
1860693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
1861693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
1862693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
1863693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
1864693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1865693365a8SJed Brown       MatStructure mstruct;
1866693365a8SJed Brown       PetscViewer vdraw,vstdout;
18676b3a5b13SJed Brown       PetscBool flg;
1868693365a8SJed Brown       if (flag_operator) {
1869693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
1870693365a8SJed Brown         Bexp = Bexp_mine;
1871693365a8SJed Brown       } else {
1872693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
1873693365a8SJed Brown         ierr = PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
1874693365a8SJed Brown         if (flg) Bexp = *B;
1875693365a8SJed Brown         else {
1876693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1877693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
1878693365a8SJed Brown           Bexp = Bexp_mine;
1879693365a8SJed Brown         }
1880693365a8SJed Brown       }
1881693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
1882693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
1883693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
1884693365a8SJed Brown       if (flag_draw || flag_contour) {
1885693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
1886693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
1887693365a8SJed Brown       } else vdraw = PETSC_NULL;
1888693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
1889693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
1890693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
1891693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
1892693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1893693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
1894693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
1895693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
1896693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
1897693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
1898693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
1899693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
1900693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
1901693365a8SJed Brown       }
1902693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
1903693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
1904693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
1905693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
1906693365a8SJed Brown     }
1907693365a8SJed Brown   }
19084c30e9fbSJed Brown   {
19096719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
19106719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
19114c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
19126719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
19134c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
19144c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
19156719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
19166719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
19176719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
19186719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
19194c30e9fbSJed Brown       Mat Bfd;
19204c30e9fbSJed Brown       MatStructure mstruct;
19214c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
19224c30e9fbSJed Brown       ISColoring iscoloring;
19234c30e9fbSJed Brown       MatFDColoring matfdcoloring;
19244c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
19254c30e9fbSJed Brown       void *funcctx;
19266719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
19274c30e9fbSJed Brown 
19284c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
19294c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
19304c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
19314c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
19324c30e9fbSJed Brown 
19334c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
19344c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
19354c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
19364c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
19374c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
19384c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
19394c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
19404c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
19414c30e9fbSJed Brown 
19424c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
19434c30e9fbSJed Brown       if (flag_draw || flag_contour) {
19444c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
19454c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
19464c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
19474c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
19486719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
19494c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
19504c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
19516719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19524c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
19534c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
19544c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
19556719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
19564c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
19576719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
19586719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
19594c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
19604c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
19614c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
19624c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
19634c30e9fbSJed Brown       }
19644c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
19656719d8e4SJed Brown 
19666719d8e4SJed Brown       if (flag_threshold) {
19676719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
19686719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
19696719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
19706719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
19716719d8e4SJed Brown           const PetscScalar *ba,*ca;
19726719d8e4SJed Brown           const PetscInt *bj,*cj;
19736719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
19746719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
19756719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
19766719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
19776719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
19786719d8e4SJed Brown           for (j=0; j<bn; j++) {
19796719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19806719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
19816719d8e4SJed Brown               maxentrycol = bj[j];
19826719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
19836719d8e4SJed Brown             }
19846719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
19856719d8e4SJed Brown               maxdiffcol = bj[j];
19866719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
19876719d8e4SJed Brown             }
19886719d8e4SJed Brown             if (rdiff > maxrdiff) {
19896719d8e4SJed Brown               maxrdiffcol = bj[j];
19906719d8e4SJed Brown               maxrdiff = rdiff;
19916719d8e4SJed Brown             }
19926719d8e4SJed Brown           }
19936719d8e4SJed Brown           if (maxrdiff > 1) {
19946719d8e4SJed 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);
19956719d8e4SJed Brown             for (j=0; j<bn; j++) {
19966719d8e4SJed Brown               PetscReal rdiff;
19976719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
19986719d8e4SJed Brown               if (rdiff > 1) {
19996719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
20006719d8e4SJed Brown               }
20016719d8e4SJed Brown             }
20026719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
20036719d8e4SJed Brown           }
20046719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
20056719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
20066719d8e4SJed Brown         }
20076719d8e4SJed Brown       }
20084c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
20094c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
20104c30e9fbSJed Brown     }
20114c30e9fbSJed Brown   }
20123a40ed3dSBarry Smith   PetscFunctionReturn(0);
20139b94acceSBarry Smith }
20149b94acceSBarry Smith 
20154a2ae208SSatish Balay #undef __FUNCT__
20164a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
20179b94acceSBarry Smith /*@C
20189b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2019044dda88SLois Curfman McInnes    location to store the matrix.
20209b94acceSBarry Smith 
20213f9fe445SBarry Smith    Logically Collective on SNES and Mat
2022c7afd0dbSLois Curfman McInnes 
20239b94acceSBarry Smith    Input Parameters:
2024c7afd0dbSLois Curfman McInnes +  snes - the SNES context
20259b94acceSBarry Smith .  A - Jacobian matrix
20269b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2027efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2028c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2029efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
20309b94acceSBarry Smith 
20319b94acceSBarry Smith    Calling sequence of func:
20328d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
20339b94acceSBarry Smith 
2034c7afd0dbSLois Curfman McInnes +  x - input vector
20359b94acceSBarry Smith .  A - Jacobian matrix
20369b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2037ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
20382b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2039c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
20409b94acceSBarry Smith 
20419b94acceSBarry Smith    Notes:
204294b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
20432cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2044ac21db08SLois Curfman McInnes 
2045ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
20469b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
20479b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
20489b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
20499b94acceSBarry Smith    throughout the global iterations.
20509b94acceSBarry Smith 
205116913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
205216913363SBarry Smith    each matrix.
205316913363SBarry Smith 
2054a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2055a8a26c1eSJed Brown    must be a MatFDColoring.
2056a8a26c1eSJed Brown 
2057c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2058c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2059c3cc8fd1SJed Brown 
206036851e7fSLois Curfman McInnes    Level: beginner
206136851e7fSLois Curfman McInnes 
20629b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
20639b94acceSBarry Smith 
20643ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
20659b94acceSBarry Smith @*/
20667087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
20679b94acceSBarry Smith {
2068dfbe8321SBarry Smith   PetscErrorCode ierr;
20696cab3a1bSJed Brown   DM             dm;
20703a7fca6bSBarry Smith 
20713a40ed3dSBarry Smith   PetscFunctionBegin;
20720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
20730700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
20740700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2075c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
207606975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
20776cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
20786cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
20793a7fca6bSBarry Smith   if (A) {
20807dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
20816bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
20829b94acceSBarry Smith     snes->jacobian = A;
20833a7fca6bSBarry Smith   }
20843a7fca6bSBarry Smith   if (B) {
20857dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
20866bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
20879b94acceSBarry Smith     snes->jacobian_pre = B;
20883a7fca6bSBarry Smith   }
20893a40ed3dSBarry Smith   PetscFunctionReturn(0);
20909b94acceSBarry Smith }
209162fef451SLois Curfman McInnes 
20924a2ae208SSatish Balay #undef __FUNCT__
20934a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2094c2aafc4cSSatish Balay /*@C
2095b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2096b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2097b4fd4287SBarry Smith 
2098c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2099c7afd0dbSLois Curfman McInnes 
2100b4fd4287SBarry Smith    Input Parameter:
2101b4fd4287SBarry Smith .  snes - the nonlinear solver context
2102b4fd4287SBarry Smith 
2103b4fd4287SBarry Smith    Output Parameters:
2104c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2105b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
210670e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
210770e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2108fee21e36SBarry Smith 
210936851e7fSLois Curfman McInnes    Level: advanced
211036851e7fSLois Curfman McInnes 
2111b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2112b4fd4287SBarry Smith @*/
21137087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2114b4fd4287SBarry Smith {
21156cab3a1bSJed Brown   PetscErrorCode ierr;
21166cab3a1bSJed Brown   DM             dm;
21176cab3a1bSJed Brown   SNESDM         sdm;
21186cab3a1bSJed Brown 
21193a40ed3dSBarry Smith   PetscFunctionBegin;
21200700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2121b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2122b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
21236cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21246cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21256cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
21266cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
21273a40ed3dSBarry Smith   PetscFunctionReturn(0);
2128b4fd4287SBarry Smith }
2129b4fd4287SBarry Smith 
21309b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
21319b94acceSBarry Smith 
21324a2ae208SSatish Balay #undef __FUNCT__
21334a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
21349b94acceSBarry Smith /*@
21359b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2136272ac6f2SLois Curfman McInnes    of a nonlinear solver.
21379b94acceSBarry Smith 
2138fee21e36SBarry Smith    Collective on SNES
2139fee21e36SBarry Smith 
2140c7afd0dbSLois Curfman McInnes    Input Parameters:
214170e92668SMatthew Knepley .  snes - the SNES context
2142c7afd0dbSLois Curfman McInnes 
2143272ac6f2SLois Curfman McInnes    Notes:
2144272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2145272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2146272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2147272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2148272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2149272ac6f2SLois Curfman McInnes 
215036851e7fSLois Curfman McInnes    Level: advanced
215136851e7fSLois Curfman McInnes 
21529b94acceSBarry Smith .keywords: SNES, nonlinear, setup
21539b94acceSBarry Smith 
21549b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
21559b94acceSBarry Smith @*/
21567087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
21579b94acceSBarry Smith {
2158dfbe8321SBarry Smith   PetscErrorCode ierr;
21596cab3a1bSJed Brown   DM             dm;
21606cab3a1bSJed Brown   SNESDM         sdm;
21613a40ed3dSBarry Smith 
21623a40ed3dSBarry Smith   PetscFunctionBegin;
21630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
21644dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
21659b94acceSBarry Smith 
21667adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
216785385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
216885385478SLisandro Dalcin   }
216985385478SLisandro Dalcin 
2170a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
217117186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
217258c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
217358c9b817SLisandro Dalcin 
217458c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
217558c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
217658c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
217758c9b817SLisandro Dalcin   }
217858c9b817SLisandro Dalcin 
21796cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
21806cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
21816cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
21826cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
21836cab3a1bSJed Brown   if (!snes->vec_func) {
21846cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2185214df951SJed Brown   }
2186efd51863SBarry Smith 
2187b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2188b710008aSBarry Smith 
21899e764e56SPeter Brune   if (!snes->linesearch) {ierr = SNESGetPetscLineSearch(snes, &snes->linesearch);}
21909e764e56SPeter Brune 
2191d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2192d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2193d25893d9SBarry Smith   }
2194d25893d9SBarry Smith 
2195410397dcSLisandro Dalcin   if (snes->ops->setup) {
2196410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2197410397dcSLisandro Dalcin   }
219858c9b817SLisandro Dalcin 
21997aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
22003a40ed3dSBarry Smith   PetscFunctionReturn(0);
22019b94acceSBarry Smith }
22029b94acceSBarry Smith 
22034a2ae208SSatish Balay #undef __FUNCT__
220437596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
220537596af1SLisandro Dalcin /*@
220637596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
220737596af1SLisandro Dalcin 
220837596af1SLisandro Dalcin    Collective on SNES
220937596af1SLisandro Dalcin 
221037596af1SLisandro Dalcin    Input Parameter:
221137596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
221237596af1SLisandro Dalcin 
2213d25893d9SBarry Smith    Level: intermediate
2214d25893d9SBarry Smith 
2215d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
221637596af1SLisandro Dalcin 
221737596af1SLisandro Dalcin .keywords: SNES, destroy
221837596af1SLisandro Dalcin 
221937596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
222037596af1SLisandro Dalcin @*/
222137596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
222237596af1SLisandro Dalcin {
222337596af1SLisandro Dalcin   PetscErrorCode ierr;
222437596af1SLisandro Dalcin 
222537596af1SLisandro Dalcin   PetscFunctionBegin;
222637596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2227d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2228d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2229d25893d9SBarry Smith     snes->user = PETSC_NULL;
2230d25893d9SBarry Smith   }
22318a23116dSBarry Smith   if (snes->pc) {
22328a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
22338a23116dSBarry Smith   }
22348a23116dSBarry Smith 
223537596af1SLisandro Dalcin   if (snes->ops->reset) {
223637596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
223737596af1SLisandro Dalcin   }
22389e764e56SPeter Brune   if (snes->ksp) {
22399e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
22409e764e56SPeter Brune   }
22419e764e56SPeter Brune 
22429e764e56SPeter Brune   if (snes->linesearch) {
22439e764e56SPeter Brune     ierr = PetscLineSearchReset(snes->linesearch);CHKERRQ(ierr);
22449e764e56SPeter Brune   }
22459e764e56SPeter Brune 
22466bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
22476bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
22486bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
22496bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
22506bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22516bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2252c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2253c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
225437596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
225537596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
225637596af1SLisandro Dalcin   PetscFunctionReturn(0);
225737596af1SLisandro Dalcin }
225837596af1SLisandro Dalcin 
225937596af1SLisandro Dalcin #undef __FUNCT__
22604a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
226152baeb72SSatish Balay /*@
22629b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
22639b94acceSBarry Smith    with SNESCreate().
22649b94acceSBarry Smith 
2265c7afd0dbSLois Curfman McInnes    Collective on SNES
2266c7afd0dbSLois Curfman McInnes 
22679b94acceSBarry Smith    Input Parameter:
22689b94acceSBarry Smith .  snes - the SNES context
22699b94acceSBarry Smith 
227036851e7fSLois Curfman McInnes    Level: beginner
227136851e7fSLois Curfman McInnes 
22729b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
22739b94acceSBarry Smith 
227463a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
22759b94acceSBarry Smith @*/
22766bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
22779b94acceSBarry Smith {
22786849ba73SBarry Smith   PetscErrorCode ierr;
22793a40ed3dSBarry Smith 
22803a40ed3dSBarry Smith   PetscFunctionBegin;
22816bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
22826bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
22836bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2284d4bb536fSBarry Smith 
22856bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
22868a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
22876b8b9a38SLisandro Dalcin 
2288be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
22896bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
22906bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
22916d4c513bSLisandro Dalcin 
22926bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
22936bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
22949e764e56SPeter Brune   ierr = PetscLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
22956b8b9a38SLisandro Dalcin 
22966bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
22976bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
22986bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
22996b8b9a38SLisandro Dalcin   }
23006bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
23016bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
23026bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
230358c9b817SLisandro Dalcin   }
2304ea630c6eSPeter Brune   ierr = PetscViewerDestroy(&(*snes)->ls_monitor);CHKERRQ(ierr);
23056bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2306a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
23073a40ed3dSBarry Smith  PetscFunctionReturn(0);
23089b94acceSBarry Smith }
23099b94acceSBarry Smith 
23109b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
23119b94acceSBarry Smith 
23124a2ae208SSatish Balay #undef __FUNCT__
2313a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2314a8054027SBarry Smith /*@
2315a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2316a8054027SBarry Smith 
23173f9fe445SBarry Smith    Logically Collective on SNES
2318a8054027SBarry Smith 
2319a8054027SBarry Smith    Input Parameters:
2320a8054027SBarry Smith +  snes - the SNES context
2321a8054027SBarry 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
23223b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2323a8054027SBarry Smith 
2324a8054027SBarry Smith    Options Database Keys:
2325a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2326a8054027SBarry Smith 
2327a8054027SBarry Smith    Notes:
2328a8054027SBarry Smith    The default is 1
2329a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2330a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2331a8054027SBarry Smith 
2332a8054027SBarry Smith    Level: intermediate
2333a8054027SBarry Smith 
2334a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2335a8054027SBarry Smith 
2336e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2337a8054027SBarry Smith 
2338a8054027SBarry Smith @*/
23397087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2340a8054027SBarry Smith {
2341a8054027SBarry Smith   PetscFunctionBegin;
23420700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2343e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2344e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2345c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2346a8054027SBarry Smith   snes->lagpreconditioner = lag;
2347a8054027SBarry Smith   PetscFunctionReturn(0);
2348a8054027SBarry Smith }
2349a8054027SBarry Smith 
2350a8054027SBarry Smith #undef __FUNCT__
2351efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2352efd51863SBarry Smith /*@
2353efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2354efd51863SBarry Smith 
2355efd51863SBarry Smith    Logically Collective on SNES
2356efd51863SBarry Smith 
2357efd51863SBarry Smith    Input Parameters:
2358efd51863SBarry Smith +  snes - the SNES context
2359efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2360efd51863SBarry Smith 
2361efd51863SBarry Smith    Options Database Keys:
2362efd51863SBarry Smith .    -snes_grid_sequence <steps>
2363efd51863SBarry Smith 
2364efd51863SBarry Smith    Level: intermediate
2365efd51863SBarry Smith 
2366c0df2a02SJed Brown    Notes:
2367c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2368c0df2a02SJed Brown 
2369efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2370efd51863SBarry Smith 
2371efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2372efd51863SBarry Smith 
2373efd51863SBarry Smith @*/
2374efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2375efd51863SBarry Smith {
2376efd51863SBarry Smith   PetscFunctionBegin;
2377efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2378efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2379efd51863SBarry Smith   snes->gridsequence = steps;
2380efd51863SBarry Smith   PetscFunctionReturn(0);
2381efd51863SBarry Smith }
2382efd51863SBarry Smith 
2383efd51863SBarry Smith #undef __FUNCT__
2384a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2385a8054027SBarry Smith /*@
2386a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2387a8054027SBarry Smith 
23883f9fe445SBarry Smith    Not Collective
2389a8054027SBarry Smith 
2390a8054027SBarry Smith    Input Parameter:
2391a8054027SBarry Smith .  snes - the SNES context
2392a8054027SBarry Smith 
2393a8054027SBarry Smith    Output Parameter:
2394a8054027SBarry 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
23953b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2396a8054027SBarry Smith 
2397a8054027SBarry Smith    Options Database Keys:
2398a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2399a8054027SBarry Smith 
2400a8054027SBarry Smith    Notes:
2401a8054027SBarry Smith    The default is 1
2402a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2403a8054027SBarry Smith 
2404a8054027SBarry Smith    Level: intermediate
2405a8054027SBarry Smith 
2406a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2407a8054027SBarry Smith 
2408a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2409a8054027SBarry Smith 
2410a8054027SBarry Smith @*/
24117087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2412a8054027SBarry Smith {
2413a8054027SBarry Smith   PetscFunctionBegin;
24140700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2415a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2416a8054027SBarry Smith   PetscFunctionReturn(0);
2417a8054027SBarry Smith }
2418a8054027SBarry Smith 
2419a8054027SBarry Smith #undef __FUNCT__
2420e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2421e35cf81dSBarry Smith /*@
2422e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2423e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2424e35cf81dSBarry Smith 
24253f9fe445SBarry Smith    Logically Collective on SNES
2426e35cf81dSBarry Smith 
2427e35cf81dSBarry Smith    Input Parameters:
2428e35cf81dSBarry Smith +  snes - the SNES context
2429e35cf81dSBarry 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
2430fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2431e35cf81dSBarry Smith 
2432e35cf81dSBarry Smith    Options Database Keys:
2433e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2434e35cf81dSBarry Smith 
2435e35cf81dSBarry Smith    Notes:
2436e35cf81dSBarry Smith    The default is 1
2437e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2438fe3ffe1eSBarry 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
2439fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2440e35cf81dSBarry Smith 
2441e35cf81dSBarry Smith    Level: intermediate
2442e35cf81dSBarry Smith 
2443e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2444e35cf81dSBarry Smith 
2445e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2446e35cf81dSBarry Smith 
2447e35cf81dSBarry Smith @*/
24487087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2449e35cf81dSBarry Smith {
2450e35cf81dSBarry Smith   PetscFunctionBegin;
24510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2452e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2453e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2454c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2455e35cf81dSBarry Smith   snes->lagjacobian = lag;
2456e35cf81dSBarry Smith   PetscFunctionReturn(0);
2457e35cf81dSBarry Smith }
2458e35cf81dSBarry Smith 
2459e35cf81dSBarry Smith #undef __FUNCT__
2460e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2461e35cf81dSBarry Smith /*@
2462e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2463e35cf81dSBarry Smith 
24643f9fe445SBarry Smith    Not Collective
2465e35cf81dSBarry Smith 
2466e35cf81dSBarry Smith    Input Parameter:
2467e35cf81dSBarry Smith .  snes - the SNES context
2468e35cf81dSBarry Smith 
2469e35cf81dSBarry Smith    Output Parameter:
2470e35cf81dSBarry 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
2471e35cf81dSBarry Smith          the Jacobian is built etc.
2472e35cf81dSBarry Smith 
2473e35cf81dSBarry Smith    Options Database Keys:
2474e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2475e35cf81dSBarry Smith 
2476e35cf81dSBarry Smith    Notes:
2477e35cf81dSBarry Smith    The default is 1
2478e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2479e35cf81dSBarry Smith 
2480e35cf81dSBarry Smith    Level: intermediate
2481e35cf81dSBarry Smith 
2482e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2483e35cf81dSBarry Smith 
2484e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2485e35cf81dSBarry Smith 
2486e35cf81dSBarry Smith @*/
24877087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2488e35cf81dSBarry Smith {
2489e35cf81dSBarry Smith   PetscFunctionBegin;
24900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2491e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2492e35cf81dSBarry Smith   PetscFunctionReturn(0);
2493e35cf81dSBarry Smith }
2494e35cf81dSBarry Smith 
2495e35cf81dSBarry Smith #undef __FUNCT__
24964a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
24979b94acceSBarry Smith /*@
2498d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
24999b94acceSBarry Smith 
25003f9fe445SBarry Smith    Logically Collective on SNES
2501c7afd0dbSLois Curfman McInnes 
25029b94acceSBarry Smith    Input Parameters:
2503c7afd0dbSLois Curfman McInnes +  snes - the SNES context
250470441072SBarry Smith .  abstol - absolute convergence tolerance
250533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
250633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
250733174efeSLois Curfman McInnes            of the change in the solution between steps
250833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2509c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2510fee21e36SBarry Smith 
251133174efeSLois Curfman McInnes    Options Database Keys:
251270441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2513c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2514c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2515c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2516c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
25179b94acceSBarry Smith 
2518d7a720efSLois Curfman McInnes    Notes:
25199b94acceSBarry Smith    The default maximum number of iterations is 50.
25209b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
25219b94acceSBarry Smith 
252236851e7fSLois Curfman McInnes    Level: intermediate
252336851e7fSLois Curfman McInnes 
252433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
25259b94acceSBarry Smith 
25262492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
25279b94acceSBarry Smith @*/
25287087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
25299b94acceSBarry Smith {
25303a40ed3dSBarry Smith   PetscFunctionBegin;
25310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2532c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2533c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2534c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2535c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2536c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2537c5eb9154SBarry Smith 
2538ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2539ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2540ab54825eSJed Brown     snes->abstol = abstol;
2541ab54825eSJed Brown   }
2542ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2543ab54825eSJed 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);
2544ab54825eSJed Brown     snes->rtol = rtol;
2545ab54825eSJed Brown   }
2546ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2547ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2548ab54825eSJed Brown     snes->xtol = stol;
2549ab54825eSJed Brown   }
2550ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2551ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2552ab54825eSJed Brown     snes->max_its = maxit;
2553ab54825eSJed Brown   }
2554ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2555ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2556ab54825eSJed Brown     snes->max_funcs = maxf;
2557ab54825eSJed Brown   }
25583a40ed3dSBarry Smith   PetscFunctionReturn(0);
25599b94acceSBarry Smith }
25609b94acceSBarry Smith 
25614a2ae208SSatish Balay #undef __FUNCT__
25624a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
25639b94acceSBarry Smith /*@
256433174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
256533174efeSLois Curfman McInnes 
2566c7afd0dbSLois Curfman McInnes    Not Collective
2567c7afd0dbSLois Curfman McInnes 
256833174efeSLois Curfman McInnes    Input Parameters:
2569c7afd0dbSLois Curfman McInnes +  snes - the SNES context
257085385478SLisandro Dalcin .  atol - absolute convergence tolerance
257133174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
257233174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
257333174efeSLois Curfman McInnes            of the change in the solution between steps
257433174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2575c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2576fee21e36SBarry Smith 
257733174efeSLois Curfman McInnes    Notes:
257833174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
257933174efeSLois Curfman McInnes 
258036851e7fSLois Curfman McInnes    Level: intermediate
258136851e7fSLois Curfman McInnes 
258233174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
258333174efeSLois Curfman McInnes 
258433174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
258533174efeSLois Curfman McInnes @*/
25867087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
258733174efeSLois Curfman McInnes {
25883a40ed3dSBarry Smith   PetscFunctionBegin;
25890700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
259085385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
259133174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
259233174efeSLois Curfman McInnes   if (stol)  *stol  = snes->xtol;
259333174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
259433174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
25953a40ed3dSBarry Smith   PetscFunctionReturn(0);
259633174efeSLois Curfman McInnes }
259733174efeSLois Curfman McInnes 
25984a2ae208SSatish Balay #undef __FUNCT__
25994a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
260033174efeSLois Curfman McInnes /*@
26019b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
26029b94acceSBarry Smith 
26033f9fe445SBarry Smith    Logically Collective on SNES
2604fee21e36SBarry Smith 
2605c7afd0dbSLois Curfman McInnes    Input Parameters:
2606c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2607c7afd0dbSLois Curfman McInnes -  tol - tolerance
2608c7afd0dbSLois Curfman McInnes 
26099b94acceSBarry Smith    Options Database Key:
2610c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
26119b94acceSBarry Smith 
261236851e7fSLois Curfman McInnes    Level: intermediate
261336851e7fSLois Curfman McInnes 
26149b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
26159b94acceSBarry Smith 
26162492ecdbSBarry Smith .seealso: SNESSetTolerances()
26179b94acceSBarry Smith @*/
26187087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
26199b94acceSBarry Smith {
26203a40ed3dSBarry Smith   PetscFunctionBegin;
26210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2622c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
26239b94acceSBarry Smith   snes->deltatol = tol;
26243a40ed3dSBarry Smith   PetscFunctionReturn(0);
26259b94acceSBarry Smith }
26269b94acceSBarry Smith 
2627df9fa365SBarry Smith /*
2628df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2629df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2630df9fa365SBarry Smith    macros instead of functions
2631df9fa365SBarry Smith */
26324a2ae208SSatish Balay #undef __FUNCT__
2633a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
26347087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2635ce1608b8SBarry Smith {
2636dfbe8321SBarry Smith   PetscErrorCode ierr;
2637ce1608b8SBarry Smith 
2638ce1608b8SBarry Smith   PetscFunctionBegin;
26390700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2640a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2641ce1608b8SBarry Smith   PetscFunctionReturn(0);
2642ce1608b8SBarry Smith }
2643ce1608b8SBarry Smith 
26444a2ae208SSatish Balay #undef __FUNCT__
2645a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
26467087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2647df9fa365SBarry Smith {
2648dfbe8321SBarry Smith   PetscErrorCode ierr;
2649df9fa365SBarry Smith 
2650df9fa365SBarry Smith   PetscFunctionBegin;
2651a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2652df9fa365SBarry Smith   PetscFunctionReturn(0);
2653df9fa365SBarry Smith }
2654df9fa365SBarry Smith 
26554a2ae208SSatish Balay #undef __FUNCT__
2656a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
26576bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2658df9fa365SBarry Smith {
2659dfbe8321SBarry Smith   PetscErrorCode ierr;
2660df9fa365SBarry Smith 
2661df9fa365SBarry Smith   PetscFunctionBegin;
2662a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2663df9fa365SBarry Smith   PetscFunctionReturn(0);
2664df9fa365SBarry Smith }
2665df9fa365SBarry Smith 
26667087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2667b271bb04SBarry Smith #undef __FUNCT__
2668b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
26697087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2670b271bb04SBarry Smith {
2671b271bb04SBarry Smith   PetscDrawLG      lg;
2672b271bb04SBarry Smith   PetscErrorCode   ierr;
2673b271bb04SBarry Smith   PetscReal        x,y,per;
2674b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2675b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2676b271bb04SBarry Smith   PetscDraw        draw;
2677b271bb04SBarry Smith   PetscFunctionBegin;
2678b271bb04SBarry Smith   if (!monctx) {
2679b271bb04SBarry Smith     MPI_Comm    comm;
2680b271bb04SBarry Smith 
2681b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2682b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2683b271bb04SBarry Smith   }
2684b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2685b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2686b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2687b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2688b271bb04SBarry Smith   x = (PetscReal) n;
2689b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2690b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2691b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2692b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2693b271bb04SBarry Smith   }
2694b271bb04SBarry Smith 
2695b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2696b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2697b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2698b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2699b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2700b271bb04SBarry Smith   x = (PetscReal) n;
2701b271bb04SBarry Smith   y = 100.0*per;
2702b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2703b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2704b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2705b271bb04SBarry Smith   }
2706b271bb04SBarry Smith 
2707b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2708b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2709b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2710b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2711b271bb04SBarry Smith   x = (PetscReal) n;
2712b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2713b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2714b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2715b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2716b271bb04SBarry Smith   }
2717b271bb04SBarry Smith 
2718b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2719b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2720b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2721b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2722b271bb04SBarry Smith   x = (PetscReal) n;
2723b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2724b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2725b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2726b271bb04SBarry Smith   }
2727b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2728b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2729b271bb04SBarry Smith   }
2730b271bb04SBarry Smith   prev = rnorm;
2731b271bb04SBarry Smith   PetscFunctionReturn(0);
2732b271bb04SBarry Smith }
2733b271bb04SBarry Smith 
2734b271bb04SBarry Smith #undef __FUNCT__
2735b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
27367087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2737b271bb04SBarry Smith {
2738b271bb04SBarry Smith   PetscErrorCode ierr;
2739b271bb04SBarry Smith 
2740b271bb04SBarry Smith   PetscFunctionBegin;
2741b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2742b271bb04SBarry Smith   PetscFunctionReturn(0);
2743b271bb04SBarry Smith }
2744b271bb04SBarry Smith 
2745b271bb04SBarry Smith #undef __FUNCT__
2746b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
27476bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2748b271bb04SBarry Smith {
2749b271bb04SBarry Smith   PetscErrorCode ierr;
2750b271bb04SBarry Smith 
2751b271bb04SBarry Smith   PetscFunctionBegin;
2752b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2753b271bb04SBarry Smith   PetscFunctionReturn(0);
2754b271bb04SBarry Smith }
2755b271bb04SBarry Smith 
27567a03ce2fSLisandro Dalcin #undef __FUNCT__
27577a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2758228d79bcSJed Brown /*@
2759228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2760228d79bcSJed Brown 
2761228d79bcSJed Brown    Collective on SNES
2762228d79bcSJed Brown 
2763228d79bcSJed Brown    Input Parameters:
2764228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2765228d79bcSJed Brown .  iter - iteration number
2766228d79bcSJed Brown -  rnorm - relative norm of the residual
2767228d79bcSJed Brown 
2768228d79bcSJed Brown    Notes:
2769228d79bcSJed Brown    This routine is called by the SNES implementations.
2770228d79bcSJed Brown    It does not typically need to be called by the user.
2771228d79bcSJed Brown 
2772228d79bcSJed Brown    Level: developer
2773228d79bcSJed Brown 
2774228d79bcSJed Brown .seealso: SNESMonitorSet()
2775228d79bcSJed Brown @*/
27767a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
27777a03ce2fSLisandro Dalcin {
27787a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
27797a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
27807a03ce2fSLisandro Dalcin 
27817a03ce2fSLisandro Dalcin   PetscFunctionBegin;
27827a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
27837a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
27847a03ce2fSLisandro Dalcin   }
27857a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
27867a03ce2fSLisandro Dalcin }
27877a03ce2fSLisandro Dalcin 
27889b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
27899b94acceSBarry Smith 
27904a2ae208SSatish Balay #undef __FUNCT__
2791a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
27929b94acceSBarry Smith /*@C
2793a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
27949b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
27959b94acceSBarry Smith    progress.
27969b94acceSBarry Smith 
27973f9fe445SBarry Smith    Logically Collective on SNES
2798fee21e36SBarry Smith 
2799c7afd0dbSLois Curfman McInnes    Input Parameters:
2800c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2801c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2802b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2803e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2804b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2805b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
28069b94acceSBarry Smith 
2807c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2808a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2809c7afd0dbSLois Curfman McInnes 
2810c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2811c7afd0dbSLois Curfman McInnes .    its - iteration number
2812c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
281340a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
28149b94acceSBarry Smith 
28159665c990SLois Curfman McInnes    Options Database Keys:
2816a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2817a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2818a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2819cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2820c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2821a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2822c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2823c7afd0dbSLois Curfman McInnes                             the options database.
28249665c990SLois Curfman McInnes 
2825639f9d9dSBarry Smith    Notes:
28266bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2827a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
28286bc08f3fSLois Curfman McInnes    order in which they were set.
2829639f9d9dSBarry Smith 
2830025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2831025f1a04SBarry Smith 
283236851e7fSLois Curfman McInnes    Level: intermediate
283336851e7fSLois Curfman McInnes 
28349b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
28359b94acceSBarry Smith 
2836a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
28379b94acceSBarry Smith @*/
2838c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
28399b94acceSBarry Smith {
2840b90d0a6eSBarry Smith   PetscInt       i;
2841649052a6SBarry Smith   PetscErrorCode ierr;
2842b90d0a6eSBarry Smith 
28433a40ed3dSBarry Smith   PetscFunctionBegin;
28440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
284517186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2846b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
2847649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2848649052a6SBarry Smith       if (monitordestroy) {
2849c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
2850649052a6SBarry Smith       }
2851b90d0a6eSBarry Smith       PetscFunctionReturn(0);
2852b90d0a6eSBarry Smith     }
2853b90d0a6eSBarry Smith   }
2854b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
2855b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
2856639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
28573a40ed3dSBarry Smith   PetscFunctionReturn(0);
28589b94acceSBarry Smith }
28599b94acceSBarry Smith 
28604a2ae208SSatish Balay #undef __FUNCT__
2861a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
28625cd90555SBarry Smith /*@C
2863a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
28645cd90555SBarry Smith 
28653f9fe445SBarry Smith    Logically Collective on SNES
2866c7afd0dbSLois Curfman McInnes 
28675cd90555SBarry Smith    Input Parameters:
28685cd90555SBarry Smith .  snes - the SNES context
28695cd90555SBarry Smith 
28701a480d89SAdministrator    Options Database Key:
2871a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
2872a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
2873c7afd0dbSLois Curfman McInnes     set via the options database
28745cd90555SBarry Smith 
28755cd90555SBarry Smith    Notes:
28765cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
28775cd90555SBarry Smith 
287836851e7fSLois Curfman McInnes    Level: intermediate
287936851e7fSLois Curfman McInnes 
28805cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
28815cd90555SBarry Smith 
2882a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
28835cd90555SBarry Smith @*/
28847087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
28855cd90555SBarry Smith {
2886d952e501SBarry Smith   PetscErrorCode ierr;
2887d952e501SBarry Smith   PetscInt       i;
2888d952e501SBarry Smith 
28895cd90555SBarry Smith   PetscFunctionBegin;
28900700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2891d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
2892d952e501SBarry Smith     if (snes->monitordestroy[i]) {
28933c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
2894d952e501SBarry Smith     }
2895d952e501SBarry Smith   }
28965cd90555SBarry Smith   snes->numbermonitors = 0;
28975cd90555SBarry Smith   PetscFunctionReturn(0);
28985cd90555SBarry Smith }
28995cd90555SBarry Smith 
29004a2ae208SSatish Balay #undef __FUNCT__
29014a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
29029b94acceSBarry Smith /*@C
29039b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
29049b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
29059b94acceSBarry Smith 
29063f9fe445SBarry Smith    Logically Collective on SNES
2907fee21e36SBarry Smith 
2908c7afd0dbSLois Curfman McInnes    Input Parameters:
2909c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2910c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
29117f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
29127f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
29139b94acceSBarry Smith 
2914c7afd0dbSLois Curfman McInnes    Calling sequence of func:
291506ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2916c7afd0dbSLois Curfman McInnes 
2917c7afd0dbSLois Curfman McInnes +    snes - the SNES context
291806ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
2919c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
2920184914b5SBarry Smith .    reason - reason for convergence/divergence
2921c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
29224b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
29234b27c08aSLois Curfman McInnes -    f - 2-norm of function
29249b94acceSBarry Smith 
292536851e7fSLois Curfman McInnes    Level: advanced
292636851e7fSLois Curfman McInnes 
29279b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
29289b94acceSBarry Smith 
292985385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
29309b94acceSBarry Smith @*/
29317087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
29329b94acceSBarry Smith {
29337f7931b9SBarry Smith   PetscErrorCode ierr;
29347f7931b9SBarry Smith 
29353a40ed3dSBarry Smith   PetscFunctionBegin;
29360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
293785385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
29387f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
29397f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
29407f7931b9SBarry Smith   }
294185385478SLisandro Dalcin   snes->ops->converged        = func;
29427f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
294385385478SLisandro Dalcin   snes->cnvP                  = cctx;
29443a40ed3dSBarry Smith   PetscFunctionReturn(0);
29459b94acceSBarry Smith }
29469b94acceSBarry Smith 
29474a2ae208SSatish Balay #undef __FUNCT__
29484a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
294952baeb72SSatish Balay /*@
2950184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2951184914b5SBarry Smith 
2952184914b5SBarry Smith    Not Collective
2953184914b5SBarry Smith 
2954184914b5SBarry Smith    Input Parameter:
2955184914b5SBarry Smith .  snes - the SNES context
2956184914b5SBarry Smith 
2957184914b5SBarry Smith    Output Parameter:
29584d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2959184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
2960184914b5SBarry Smith 
2961184914b5SBarry Smith    Level: intermediate
2962184914b5SBarry Smith 
2963184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
2964184914b5SBarry Smith 
2965184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
2966184914b5SBarry Smith 
296785385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2968184914b5SBarry Smith @*/
29697087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2970184914b5SBarry Smith {
2971184914b5SBarry Smith   PetscFunctionBegin;
29720700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
29734482741eSBarry Smith   PetscValidPointer(reason,2);
2974184914b5SBarry Smith   *reason = snes->reason;
2975184914b5SBarry Smith   PetscFunctionReturn(0);
2976184914b5SBarry Smith }
2977184914b5SBarry Smith 
29784a2ae208SSatish Balay #undef __FUNCT__
29794a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
2980c9005455SLois Curfman McInnes /*@
2981c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2982c9005455SLois Curfman McInnes 
29833f9fe445SBarry Smith    Logically Collective on SNES
2984fee21e36SBarry Smith 
2985c7afd0dbSLois Curfman McInnes    Input Parameters:
2986c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
29878c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
2988cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
2989758f92a0SBarry Smith .  na  - size of a and its
299064731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2991758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
2992c7afd0dbSLois Curfman McInnes 
2993308dcc3eSBarry Smith    Notes:
2994308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2995308dcc3eSBarry Smith    default array of length 10000 is allocated.
2996308dcc3eSBarry Smith 
2997c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
2998c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
2999c9005455SLois Curfman McInnes    during the section of code that is being timed.
3000c9005455SLois Curfman McInnes 
300136851e7fSLois Curfman McInnes    Level: intermediate
300236851e7fSLois Curfman McInnes 
3003c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3004758f92a0SBarry Smith 
300508405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3006758f92a0SBarry Smith 
3007c9005455SLois Curfman McInnes @*/
30087087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3009c9005455SLois Curfman McInnes {
3010308dcc3eSBarry Smith   PetscErrorCode ierr;
3011308dcc3eSBarry Smith 
30123a40ed3dSBarry Smith   PetscFunctionBegin;
30130700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
30144482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3015a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3016308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3017308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3018308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3019308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3020308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3021308dcc3eSBarry Smith   }
3022c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3023758f92a0SBarry Smith   snes->conv_hist_its   = its;
3024758f92a0SBarry Smith   snes->conv_hist_max   = na;
3025a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3026758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3027758f92a0SBarry Smith   PetscFunctionReturn(0);
3028758f92a0SBarry Smith }
3029758f92a0SBarry Smith 
3030308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3031c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3032c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3033308dcc3eSBarry Smith EXTERN_C_BEGIN
3034308dcc3eSBarry Smith #undef __FUNCT__
3035308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3036308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3037308dcc3eSBarry Smith {
3038308dcc3eSBarry Smith   mxArray        *mat;
3039308dcc3eSBarry Smith   PetscInt       i;
3040308dcc3eSBarry Smith   PetscReal      *ar;
3041308dcc3eSBarry Smith 
3042308dcc3eSBarry Smith   PetscFunctionBegin;
3043308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3044308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3045308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3046308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3047308dcc3eSBarry Smith   }
3048308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3049308dcc3eSBarry Smith }
3050308dcc3eSBarry Smith EXTERN_C_END
3051308dcc3eSBarry Smith #endif
3052308dcc3eSBarry Smith 
3053308dcc3eSBarry Smith 
30544a2ae208SSatish Balay #undef __FUNCT__
30554a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
30560c4c9dddSBarry Smith /*@C
3057758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3058758f92a0SBarry Smith 
30593f9fe445SBarry Smith    Not Collective
3060758f92a0SBarry Smith 
3061758f92a0SBarry Smith    Input Parameter:
3062758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3063758f92a0SBarry Smith 
3064758f92a0SBarry Smith    Output Parameters:
3065758f92a0SBarry Smith .  a   - array to hold history
3066758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3067758f92a0SBarry Smith          negative if not converged) for each solve.
3068758f92a0SBarry Smith -  na  - size of a and its
3069758f92a0SBarry Smith 
3070758f92a0SBarry Smith    Notes:
3071758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3072758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3073758f92a0SBarry Smith 
3074758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3075758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3076758f92a0SBarry Smith    during the section of code that is being timed.
3077758f92a0SBarry Smith 
3078758f92a0SBarry Smith    Level: intermediate
3079758f92a0SBarry Smith 
3080758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3081758f92a0SBarry Smith 
3082758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3083758f92a0SBarry Smith 
3084758f92a0SBarry Smith @*/
30857087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3086758f92a0SBarry Smith {
3087758f92a0SBarry Smith   PetscFunctionBegin;
30880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3089758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3090758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3091758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
30923a40ed3dSBarry Smith   PetscFunctionReturn(0);
3093c9005455SLois Curfman McInnes }
3094c9005455SLois Curfman McInnes 
3095e74ef692SMatthew Knepley #undef __FUNCT__
3096e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3097ac226902SBarry Smith /*@C
309876b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3099eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
31007e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
310176b2cf59SMatthew Knepley 
31023f9fe445SBarry Smith   Logically Collective on SNES
310376b2cf59SMatthew Knepley 
310476b2cf59SMatthew Knepley   Input Parameters:
310576b2cf59SMatthew Knepley . snes - The nonlinear solver context
310676b2cf59SMatthew Knepley . func - The function
310776b2cf59SMatthew Knepley 
310876b2cf59SMatthew Knepley   Calling sequence of func:
3109b5d30489SBarry Smith . func (SNES snes, PetscInt step);
311076b2cf59SMatthew Knepley 
311176b2cf59SMatthew Knepley . step - The current step of the iteration
311276b2cf59SMatthew Knepley 
3113fe97e370SBarry Smith   Level: advanced
3114fe97e370SBarry Smith 
3115fe97e370SBarry 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()
3116fe97e370SBarry Smith         This is not used by most users.
311776b2cf59SMatthew Knepley 
311876b2cf59SMatthew Knepley .keywords: SNES, update
3119b5d30489SBarry Smith 
312085385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
312176b2cf59SMatthew Knepley @*/
31227087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
312376b2cf59SMatthew Knepley {
312476b2cf59SMatthew Knepley   PetscFunctionBegin;
31250700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3126e7788613SBarry Smith   snes->ops->update = func;
312776b2cf59SMatthew Knepley   PetscFunctionReturn(0);
312876b2cf59SMatthew Knepley }
312976b2cf59SMatthew Knepley 
3130e74ef692SMatthew Knepley #undef __FUNCT__
3131e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
313276b2cf59SMatthew Knepley /*@
313376b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
313476b2cf59SMatthew Knepley 
313576b2cf59SMatthew Knepley   Not collective
313676b2cf59SMatthew Knepley 
313776b2cf59SMatthew Knepley   Input Parameters:
313876b2cf59SMatthew Knepley . snes - The nonlinear solver context
313976b2cf59SMatthew Knepley . step - The current step of the iteration
314076b2cf59SMatthew Knepley 
3141205452f4SMatthew Knepley   Level: intermediate
3142205452f4SMatthew Knepley 
314376b2cf59SMatthew Knepley .keywords: SNES, update
3144a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
314576b2cf59SMatthew Knepley @*/
31467087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
314776b2cf59SMatthew Knepley {
314876b2cf59SMatthew Knepley   PetscFunctionBegin;
314976b2cf59SMatthew Knepley   PetscFunctionReturn(0);
315076b2cf59SMatthew Knepley }
315176b2cf59SMatthew Knepley 
31524a2ae208SSatish Balay #undef __FUNCT__
31534a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
31549b94acceSBarry Smith /*
31559b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
31569b94acceSBarry Smith    positive parameter delta.
31579b94acceSBarry Smith 
31589b94acceSBarry Smith     Input Parameters:
3159c7afd0dbSLois Curfman McInnes +   snes - the SNES context
31609b94acceSBarry Smith .   y - approximate solution of linear system
31619b94acceSBarry Smith .   fnorm - 2-norm of current function
3162c7afd0dbSLois Curfman McInnes -   delta - trust region size
31639b94acceSBarry Smith 
31649b94acceSBarry Smith     Output Parameters:
3165c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
31669b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
31679b94acceSBarry Smith     region, and exceeds zero otherwise.
3168c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
31699b94acceSBarry Smith 
31709b94acceSBarry Smith     Note:
31714b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
31729b94acceSBarry Smith     is set to be the maximum allowable step size.
31739b94acceSBarry Smith 
31749b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
31759b94acceSBarry Smith */
3176dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
31779b94acceSBarry Smith {
3178064f8208SBarry Smith   PetscReal      nrm;
3179ea709b57SSatish Balay   PetscScalar    cnorm;
3180dfbe8321SBarry Smith   PetscErrorCode ierr;
31813a40ed3dSBarry Smith 
31823a40ed3dSBarry Smith   PetscFunctionBegin;
31830700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31840700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3185c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3186184914b5SBarry Smith 
3187064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3188064f8208SBarry Smith   if (nrm > *delta) {
3189064f8208SBarry Smith      nrm = *delta/nrm;
3190064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3191064f8208SBarry Smith      cnorm = nrm;
31922dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
31939b94acceSBarry Smith      *ynorm = *delta;
31949b94acceSBarry Smith   } else {
31959b94acceSBarry Smith      *gpnorm = 0.0;
3196064f8208SBarry Smith      *ynorm = nrm;
31979b94acceSBarry Smith   }
31983a40ed3dSBarry Smith   PetscFunctionReturn(0);
31999b94acceSBarry Smith }
32009b94acceSBarry Smith 
32014a2ae208SSatish Balay #undef __FUNCT__
32024a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
32036ce558aeSBarry Smith /*@C
3204f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3205f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
32069b94acceSBarry Smith 
3207c7afd0dbSLois Curfman McInnes    Collective on SNES
3208c7afd0dbSLois Curfman McInnes 
3209b2002411SLois Curfman McInnes    Input Parameters:
3210c7afd0dbSLois Curfman McInnes +  snes - the SNES context
32113cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
321285385478SLisandro Dalcin -  x - the solution vector.
32139b94acceSBarry Smith 
3214b2002411SLois Curfman McInnes    Notes:
32158ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
32168ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
32178ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
32188ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
32198ddd3da0SLois Curfman McInnes 
322036851e7fSLois Curfman McInnes    Level: beginner
322136851e7fSLois Curfman McInnes 
32229b94acceSBarry Smith .keywords: SNES, nonlinear, solve
32239b94acceSBarry Smith 
3224c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
32259b94acceSBarry Smith @*/
32267087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
32279b94acceSBarry Smith {
3228dfbe8321SBarry Smith   PetscErrorCode ierr;
3229ace3abfcSBarry Smith   PetscBool      flg;
3230eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3231eabae89aSBarry Smith   PetscViewer    viewer;
3232efd51863SBarry Smith   PetscInt       grid;
3233a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3234052efed2SBarry Smith 
32353a40ed3dSBarry Smith   PetscFunctionBegin;
32360700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3237a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3238a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
32390700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
324085385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
324185385478SLisandro Dalcin 
3242a69afd8bSBarry Smith   if (!x && snes->dm) {
3243a69afd8bSBarry Smith     ierr = DMCreateGlobalVector(snes->dm,&xcreated);CHKERRQ(ierr);
3244a69afd8bSBarry Smith     x    = xcreated;
3245a69afd8bSBarry Smith   }
3246a69afd8bSBarry Smith 
3247a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3248efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3249efd51863SBarry Smith 
325085385478SLisandro Dalcin     /* set solution vector */
3251efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
32526bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
325385385478SLisandro Dalcin     snes->vec_sol = x;
325485385478SLisandro Dalcin     /* set afine vector if provided */
325585385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
32566bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
325785385478SLisandro Dalcin     snes->vec_rhs = b;
325885385478SLisandro Dalcin 
325970e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
32603f149594SLisandro Dalcin 
32617eee914bSBarry Smith     if (!grid) {
32627eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3263d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3264dd568438SSatish Balay       } else if (snes->dm) {
3265dd568438SSatish Balay         PetscBool ig;
3266dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3267dd568438SSatish Balay         if (ig) {
32687eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
32697eee914bSBarry Smith         }
3270d25893d9SBarry Smith       }
3271dd568438SSatish Balay     }
3272d25893d9SBarry Smith 
3273abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
327450ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3275d5e45103SBarry Smith 
32763f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32774936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
327885385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
32794936397dSBarry Smith     if (snes->domainerror){
32804936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
32814936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
32824936397dSBarry Smith     }
328317186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
32843f149594SLisandro Dalcin 
32857adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3286eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
32877adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3288eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
32896bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3290eabae89aSBarry Smith     }
3291eabae89aSBarry Smith 
329290d69ab7SBarry Smith     flg  = PETSC_FALSE;
3293acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3294da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
32955968eb51SBarry Smith     if (snes->printreason) {
3296a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
32975968eb51SBarry Smith       if (snes->reason > 0) {
3298c7e7b494SJed 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);
32995968eb51SBarry Smith       } else {
3300c7e7b494SJed 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);
33015968eb51SBarry Smith       }
3302a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
33035968eb51SBarry Smith     }
33045968eb51SBarry Smith 
33058501fc72SJed Brown     flg = PETSC_FALSE;
33068501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
33078501fc72SJed Brown     if (flg) {
33088501fc72SJed Brown       PetscViewer viewer;
33098501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
33108501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
33118501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
33128501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
33138501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
33148501fc72SJed Brown     }
33158501fc72SJed Brown 
3316e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3317efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3318efd51863SBarry Smith       DM  fine;
3319efd51863SBarry Smith       Vec xnew;
3320efd51863SBarry Smith       Mat interp;
3321efd51863SBarry Smith 
3322efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3323e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3324efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3325efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3326efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3327efd51863SBarry Smith       x    = xnew;
3328efd51863SBarry Smith 
3329efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3330efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3331efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3332a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3333efd51863SBarry Smith     }
3334efd51863SBarry Smith   }
3335a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
33363a40ed3dSBarry Smith   PetscFunctionReturn(0);
33379b94acceSBarry Smith }
33389b94acceSBarry Smith 
33399b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
33409b94acceSBarry Smith 
33414a2ae208SSatish Balay #undef __FUNCT__
33424a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
334382bf6240SBarry Smith /*@C
33444b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
33459b94acceSBarry Smith 
3346fee21e36SBarry Smith    Collective on SNES
3347fee21e36SBarry Smith 
3348c7afd0dbSLois Curfman McInnes    Input Parameters:
3349c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3350454a90a3SBarry Smith -  type - a known method
3351c7afd0dbSLois Curfman McInnes 
3352c7afd0dbSLois Curfman McInnes    Options Database Key:
3353454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3354c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3355ae12b187SLois Curfman McInnes 
33569b94acceSBarry Smith    Notes:
3357e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
33584b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3359c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33604b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3361c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
33629b94acceSBarry Smith 
3363ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3364ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3365ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3366ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3367ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3368ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3369ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3370ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3371ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3372b0a32e0cSBarry Smith   appropriate method.
337336851e7fSLois Curfman McInnes 
337436851e7fSLois Curfman McInnes   Level: intermediate
3375a703fe33SLois Curfman McInnes 
3376454a90a3SBarry Smith .keywords: SNES, set, type
3377435da068SBarry Smith 
3378435da068SBarry Smith .seealso: SNESType, SNESCreate()
3379435da068SBarry Smith 
33809b94acceSBarry Smith @*/
33817087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
33829b94acceSBarry Smith {
3383dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3384ace3abfcSBarry Smith   PetscBool      match;
33853a40ed3dSBarry Smith 
33863a40ed3dSBarry Smith   PetscFunctionBegin;
33870700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33884482741eSBarry Smith   PetscValidCharPointer(type,2);
338982bf6240SBarry Smith 
33906831982aSBarry Smith   ierr = PetscTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
33910f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
339292ff6ae8SBarry Smith 
33934b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3394e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
339575396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3396b5c23020SJed Brown   if (snes->ops->destroy) {
3397b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3398b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3399b5c23020SJed Brown   }
340075396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
340175396ef9SLisandro Dalcin   snes->ops->setup          = 0;
340275396ef9SLisandro Dalcin   snes->ops->solve          = 0;
340375396ef9SLisandro Dalcin   snes->ops->view           = 0;
340475396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
340575396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
340675396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
340775396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3408454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
340903bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
34109fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
34119fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
34129fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
34139fb22e1aSBarry Smith   }
34149fb22e1aSBarry Smith #endif
34153a40ed3dSBarry Smith   PetscFunctionReturn(0);
34169b94acceSBarry Smith }
34179b94acceSBarry Smith 
3418a847f771SSatish Balay 
34199b94acceSBarry Smith /* --------------------------------------------------------------------- */
34204a2ae208SSatish Balay #undef __FUNCT__
34214a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
342252baeb72SSatish Balay /*@
34239b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3424f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
34259b94acceSBarry Smith 
3426fee21e36SBarry Smith    Not Collective
3427fee21e36SBarry Smith 
342836851e7fSLois Curfman McInnes    Level: advanced
342936851e7fSLois Curfman McInnes 
34309b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
34319b94acceSBarry Smith 
34329b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
34339b94acceSBarry Smith @*/
34347087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
34359b94acceSBarry Smith {
3436dfbe8321SBarry Smith   PetscErrorCode ierr;
343782bf6240SBarry Smith 
34383a40ed3dSBarry Smith   PetscFunctionBegin;
34391441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
34404c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
34413a40ed3dSBarry Smith   PetscFunctionReturn(0);
34429b94acceSBarry Smith }
34439b94acceSBarry Smith 
34444a2ae208SSatish Balay #undef __FUNCT__
34454a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
34469b94acceSBarry Smith /*@C
34479a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
34489b94acceSBarry Smith 
3449c7afd0dbSLois Curfman McInnes    Not Collective
3450c7afd0dbSLois Curfman McInnes 
34519b94acceSBarry Smith    Input Parameter:
34524b0e389bSBarry Smith .  snes - nonlinear solver context
34539b94acceSBarry Smith 
34549b94acceSBarry Smith    Output Parameter:
34553a7fca6bSBarry Smith .  type - SNES method (a character string)
34569b94acceSBarry Smith 
345736851e7fSLois Curfman McInnes    Level: intermediate
345836851e7fSLois Curfman McInnes 
3459454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
34609b94acceSBarry Smith @*/
34617087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
34629b94acceSBarry Smith {
34633a40ed3dSBarry Smith   PetscFunctionBegin;
34640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34654482741eSBarry Smith   PetscValidPointer(type,2);
34667adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
34673a40ed3dSBarry Smith   PetscFunctionReturn(0);
34689b94acceSBarry Smith }
34699b94acceSBarry Smith 
34704a2ae208SSatish Balay #undef __FUNCT__
34714a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
347252baeb72SSatish Balay /*@
34739b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3474c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
34759b94acceSBarry Smith 
3476c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3477c7afd0dbSLois Curfman McInnes 
34789b94acceSBarry Smith    Input Parameter:
34799b94acceSBarry Smith .  snes - the SNES context
34809b94acceSBarry Smith 
34819b94acceSBarry Smith    Output Parameter:
34829b94acceSBarry Smith .  x - the solution
34839b94acceSBarry Smith 
348470e92668SMatthew Knepley    Level: intermediate
348536851e7fSLois Curfman McInnes 
34869b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
34879b94acceSBarry Smith 
348885385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
34899b94acceSBarry Smith @*/
34907087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
34919b94acceSBarry Smith {
34923a40ed3dSBarry Smith   PetscFunctionBegin;
34930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
34944482741eSBarry Smith   PetscValidPointer(x,2);
349585385478SLisandro Dalcin   *x = snes->vec_sol;
349670e92668SMatthew Knepley   PetscFunctionReturn(0);
349770e92668SMatthew Knepley }
349870e92668SMatthew Knepley 
349970e92668SMatthew Knepley #undef __FUNCT__
35004a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
350152baeb72SSatish Balay /*@
35029b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
35039b94acceSBarry Smith    stored.
35049b94acceSBarry Smith 
3505c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3506c7afd0dbSLois Curfman McInnes 
35079b94acceSBarry Smith    Input Parameter:
35089b94acceSBarry Smith .  snes - the SNES context
35099b94acceSBarry Smith 
35109b94acceSBarry Smith    Output Parameter:
35119b94acceSBarry Smith .  x - the solution update
35129b94acceSBarry Smith 
351336851e7fSLois Curfman McInnes    Level: advanced
351436851e7fSLois Curfman McInnes 
35159b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
35169b94acceSBarry Smith 
351785385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
35189b94acceSBarry Smith @*/
35197087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
35209b94acceSBarry Smith {
35213a40ed3dSBarry Smith   PetscFunctionBegin;
35220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35234482741eSBarry Smith   PetscValidPointer(x,2);
352485385478SLisandro Dalcin   *x = snes->vec_sol_update;
35253a40ed3dSBarry Smith   PetscFunctionReturn(0);
35269b94acceSBarry Smith }
35279b94acceSBarry Smith 
35284a2ae208SSatish Balay #undef __FUNCT__
35294a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
35309b94acceSBarry Smith /*@C
35313638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
35329b94acceSBarry Smith 
3533a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3534c7afd0dbSLois Curfman McInnes 
35359b94acceSBarry Smith    Input Parameter:
35369b94acceSBarry Smith .  snes - the SNES context
35379b94acceSBarry Smith 
35389b94acceSBarry Smith    Output Parameter:
35397bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
354070e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
354170e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
35429b94acceSBarry Smith 
354336851e7fSLois Curfman McInnes    Level: advanced
354436851e7fSLois Curfman McInnes 
3545a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
35469b94acceSBarry Smith 
35474b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
35489b94acceSBarry Smith @*/
35497087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
35509b94acceSBarry Smith {
3551a63bb30eSJed Brown   PetscErrorCode ierr;
35526cab3a1bSJed Brown   DM             dm;
3553a63bb30eSJed Brown 
35543a40ed3dSBarry Smith   PetscFunctionBegin;
35550700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3556a63bb30eSJed Brown   if (r) {
3557a63bb30eSJed Brown     if (!snes->vec_func) {
3558a63bb30eSJed Brown       if (snes->vec_rhs) {
3559a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3560a63bb30eSJed Brown       } else if (snes->vec_sol) {
3561a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3562a63bb30eSJed Brown       } else if (snes->dm) {
3563a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3564a63bb30eSJed Brown       }
3565a63bb30eSJed Brown     }
3566a63bb30eSJed Brown     *r = snes->vec_func;
3567a63bb30eSJed Brown   }
35686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
35696cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
35703a40ed3dSBarry Smith   PetscFunctionReturn(0);
35719b94acceSBarry Smith }
35729b94acceSBarry Smith 
3573c79ef259SPeter Brune /*@C
3574c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3575c79ef259SPeter Brune 
3576c79ef259SPeter Brune    Input Parameter:
3577c79ef259SPeter Brune .  snes - the SNES context
3578c79ef259SPeter Brune 
3579c79ef259SPeter Brune    Output Parameter:
3580c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3581c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3582c79ef259SPeter Brune 
3583c79ef259SPeter Brune    Level: advanced
3584c79ef259SPeter Brune 
3585c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3586c79ef259SPeter Brune 
3587c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3588c79ef259SPeter Brune @*/
3589c79ef259SPeter Brune 
35904a2ae208SSatish Balay #undef __FUNCT__
3591646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3592646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3593646217ecSPeter Brune {
35946cab3a1bSJed Brown   PetscErrorCode ierr;
35956cab3a1bSJed Brown   DM             dm;
35966cab3a1bSJed Brown 
3597646217ecSPeter Brune   PetscFunctionBegin;
3598646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35996cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
36006cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3601646217ecSPeter Brune   PetscFunctionReturn(0);
3602646217ecSPeter Brune }
3603646217ecSPeter Brune 
36044a2ae208SSatish Balay #undef __FUNCT__
36054a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
36063c7409f5SSatish Balay /*@C
36073c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3608d850072dSLois Curfman McInnes    SNES options in the database.
36093c7409f5SSatish Balay 
36103f9fe445SBarry Smith    Logically Collective on SNES
3611fee21e36SBarry Smith 
3612c7afd0dbSLois Curfman McInnes    Input Parameter:
3613c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3614c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3615c7afd0dbSLois Curfman McInnes 
3616d850072dSLois Curfman McInnes    Notes:
3617a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3618c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3619d850072dSLois Curfman McInnes 
362036851e7fSLois Curfman McInnes    Level: advanced
362136851e7fSLois Curfman McInnes 
36223c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3623a86d99e1SLois Curfman McInnes 
3624a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
36253c7409f5SSatish Balay @*/
36267087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
36273c7409f5SSatish Balay {
3628dfbe8321SBarry Smith   PetscErrorCode ierr;
36293c7409f5SSatish Balay 
36303a40ed3dSBarry Smith   PetscFunctionBegin;
36310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3632639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36331cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
363494b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36353a40ed3dSBarry Smith   PetscFunctionReturn(0);
36363c7409f5SSatish Balay }
36373c7409f5SSatish Balay 
36384a2ae208SSatish Balay #undef __FUNCT__
36394a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
36403c7409f5SSatish Balay /*@C
3641f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3642d850072dSLois Curfman McInnes    SNES options in the database.
36433c7409f5SSatish Balay 
36443f9fe445SBarry Smith    Logically Collective on SNES
3645fee21e36SBarry Smith 
3646c7afd0dbSLois Curfman McInnes    Input Parameters:
3647c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3648c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3649c7afd0dbSLois Curfman McInnes 
3650d850072dSLois Curfman McInnes    Notes:
3651a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3652c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3653d850072dSLois Curfman McInnes 
365436851e7fSLois Curfman McInnes    Level: advanced
365536851e7fSLois Curfman McInnes 
36563c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3657a86d99e1SLois Curfman McInnes 
3658a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
36593c7409f5SSatish Balay @*/
36607087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
36613c7409f5SSatish Balay {
3662dfbe8321SBarry Smith   PetscErrorCode ierr;
36633c7409f5SSatish Balay 
36643a40ed3dSBarry Smith   PetscFunctionBegin;
36650700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3666639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
36671cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
366894b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
36693a40ed3dSBarry Smith   PetscFunctionReturn(0);
36703c7409f5SSatish Balay }
36713c7409f5SSatish Balay 
36724a2ae208SSatish Balay #undef __FUNCT__
36734a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
36749ab63eb5SSatish Balay /*@C
36753c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
36763c7409f5SSatish Balay    SNES options in the database.
36773c7409f5SSatish Balay 
3678c7afd0dbSLois Curfman McInnes    Not Collective
3679c7afd0dbSLois Curfman McInnes 
36803c7409f5SSatish Balay    Input Parameter:
36813c7409f5SSatish Balay .  snes - the SNES context
36823c7409f5SSatish Balay 
36833c7409f5SSatish Balay    Output Parameter:
36843c7409f5SSatish Balay .  prefix - pointer to the prefix string used
36853c7409f5SSatish Balay 
36864ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
36879ab63eb5SSatish Balay    sufficient length to hold the prefix.
36889ab63eb5SSatish Balay 
368936851e7fSLois Curfman McInnes    Level: advanced
369036851e7fSLois Curfman McInnes 
36913c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3692a86d99e1SLois Curfman McInnes 
3693a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
36943c7409f5SSatish Balay @*/
36957087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
36963c7409f5SSatish Balay {
3697dfbe8321SBarry Smith   PetscErrorCode ierr;
36983c7409f5SSatish Balay 
36993a40ed3dSBarry Smith   PetscFunctionBegin;
37000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3701639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37023a40ed3dSBarry Smith   PetscFunctionReturn(0);
37033c7409f5SSatish Balay }
37043c7409f5SSatish Balay 
3705b2002411SLois Curfman McInnes 
37064a2ae208SSatish Balay #undef __FUNCT__
37074a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
37083cea93caSBarry Smith /*@C
37093cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
37103cea93caSBarry Smith 
37117f6c08e0SMatthew Knepley   Level: advanced
37123cea93caSBarry Smith @*/
37137087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3714b2002411SLois Curfman McInnes {
3715e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3716dfbe8321SBarry Smith   PetscErrorCode ierr;
3717b2002411SLois Curfman McInnes 
3718b2002411SLois Curfman McInnes   PetscFunctionBegin;
3719b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3720c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3721b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3722b2002411SLois Curfman McInnes }
3723da9b6338SBarry Smith 
3724da9b6338SBarry Smith #undef __FUNCT__
3725da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
37267087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3727da9b6338SBarry Smith {
3728dfbe8321SBarry Smith   PetscErrorCode ierr;
372977431f27SBarry Smith   PetscInt       N,i,j;
3730da9b6338SBarry Smith   Vec            u,uh,fh;
3731da9b6338SBarry Smith   PetscScalar    value;
3732da9b6338SBarry Smith   PetscReal      norm;
3733da9b6338SBarry Smith 
3734da9b6338SBarry Smith   PetscFunctionBegin;
3735da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3736da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3737da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3738da9b6338SBarry Smith 
3739da9b6338SBarry Smith   /* currently only works for sequential */
3740da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3741da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3742da9b6338SBarry Smith   for (i=0; i<N; i++) {
3743da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
374477431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3745da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3746ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3747da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
37483ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3749da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
375077431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3751da9b6338SBarry Smith       value = -value;
3752da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3753da9b6338SBarry Smith     }
3754da9b6338SBarry Smith   }
37556bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
37566bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3757da9b6338SBarry Smith   PetscFunctionReturn(0);
3758da9b6338SBarry Smith }
375971f87433Sdalcinl 
376071f87433Sdalcinl #undef __FUNCT__
3761fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
376271f87433Sdalcinl /*@
3763fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
376471f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
376571f87433Sdalcinl    Newton method.
376671f87433Sdalcinl 
37673f9fe445SBarry Smith    Logically Collective on SNES
376871f87433Sdalcinl 
376971f87433Sdalcinl    Input Parameters:
377071f87433Sdalcinl +  snes - SNES context
377171f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
377271f87433Sdalcinl 
377364ba62caSBarry Smith     Options Database:
377464ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
377564ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
377664ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
377764ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
377864ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
377964ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
378064ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
378164ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
378264ba62caSBarry Smith 
378371f87433Sdalcinl    Notes:
378471f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
378571f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
378671f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
378771f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
378871f87433Sdalcinl    solver.
378971f87433Sdalcinl 
379071f87433Sdalcinl    Level: advanced
379171f87433Sdalcinl 
379271f87433Sdalcinl    Reference:
379371f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
379471f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
379571f87433Sdalcinl 
379671f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
379771f87433Sdalcinl 
3798fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
379971f87433Sdalcinl @*/
38007087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
380171f87433Sdalcinl {
380271f87433Sdalcinl   PetscFunctionBegin;
38030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3804acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
380571f87433Sdalcinl   snes->ksp_ewconv = flag;
380671f87433Sdalcinl   PetscFunctionReturn(0);
380771f87433Sdalcinl }
380871f87433Sdalcinl 
380971f87433Sdalcinl #undef __FUNCT__
3810fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
381171f87433Sdalcinl /*@
3812fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
381371f87433Sdalcinl    for computing relative tolerance for linear solvers within an
381471f87433Sdalcinl    inexact Newton method.
381571f87433Sdalcinl 
381671f87433Sdalcinl    Not Collective
381771f87433Sdalcinl 
381871f87433Sdalcinl    Input Parameter:
381971f87433Sdalcinl .  snes - SNES context
382071f87433Sdalcinl 
382171f87433Sdalcinl    Output Parameter:
382271f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
382371f87433Sdalcinl 
382471f87433Sdalcinl    Notes:
382571f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
382671f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
382771f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
382871f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
382971f87433Sdalcinl    solver.
383071f87433Sdalcinl 
383171f87433Sdalcinl    Level: advanced
383271f87433Sdalcinl 
383371f87433Sdalcinl    Reference:
383471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
383571f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
383671f87433Sdalcinl 
383771f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
383871f87433Sdalcinl 
3839fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
384071f87433Sdalcinl @*/
38417087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
384271f87433Sdalcinl {
384371f87433Sdalcinl   PetscFunctionBegin;
38440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
384571f87433Sdalcinl   PetscValidPointer(flag,2);
384671f87433Sdalcinl   *flag = snes->ksp_ewconv;
384771f87433Sdalcinl   PetscFunctionReturn(0);
384871f87433Sdalcinl }
384971f87433Sdalcinl 
385071f87433Sdalcinl #undef __FUNCT__
3851fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
385271f87433Sdalcinl /*@
3853fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
385471f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
385571f87433Sdalcinl    Newton method.
385671f87433Sdalcinl 
38573f9fe445SBarry Smith    Logically Collective on SNES
385871f87433Sdalcinl 
385971f87433Sdalcinl    Input Parameters:
386071f87433Sdalcinl +    snes - SNES context
386171f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
386271f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
386371f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
386471f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
386571f87433Sdalcinl              (0 <= gamma2 <= 1)
386671f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
386771f87433Sdalcinl .    alpha2 - power for safeguard
386871f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
386971f87433Sdalcinl 
387071f87433Sdalcinl    Note:
387171f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
387271f87433Sdalcinl 
387371f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
387471f87433Sdalcinl 
387571f87433Sdalcinl    Level: advanced
387671f87433Sdalcinl 
387771f87433Sdalcinl    Reference:
387871f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
387971f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
388071f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
388171f87433Sdalcinl 
388271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
388371f87433Sdalcinl 
3884fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
388571f87433Sdalcinl @*/
38867087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
388771f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
388871f87433Sdalcinl {
3889fa9f3622SBarry Smith   SNESKSPEW *kctx;
389071f87433Sdalcinl   PetscFunctionBegin;
38910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3892fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3893e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3894c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
3895c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
3896c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
3897c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
3898c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
3899c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
3900c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
390171f87433Sdalcinl 
390271f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
390371f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
390471f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
390571f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
390671f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
390771f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
390871f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
390971f87433Sdalcinl 
391071f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
3911e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
391271f87433Sdalcinl   }
391371f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3914e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
391571f87433Sdalcinl   }
391671f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3917e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
391871f87433Sdalcinl   }
391971f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3920e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
392171f87433Sdalcinl   }
392271f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3923e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
392471f87433Sdalcinl   }
392571f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3926e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
392771f87433Sdalcinl   }
392871f87433Sdalcinl   PetscFunctionReturn(0);
392971f87433Sdalcinl }
393071f87433Sdalcinl 
393171f87433Sdalcinl #undef __FUNCT__
3932fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
393371f87433Sdalcinl /*@
3934fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
393571f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
393671f87433Sdalcinl    Newton method.
393771f87433Sdalcinl 
393871f87433Sdalcinl    Not Collective
393971f87433Sdalcinl 
394071f87433Sdalcinl    Input Parameters:
394171f87433Sdalcinl      snes - SNES context
394271f87433Sdalcinl 
394371f87433Sdalcinl    Output Parameters:
394471f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
394571f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
394671f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
394771f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
394871f87433Sdalcinl              (0 <= gamma2 <= 1)
394971f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
395071f87433Sdalcinl .    alpha2 - power for safeguard
395171f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
395271f87433Sdalcinl 
395371f87433Sdalcinl    Level: advanced
395471f87433Sdalcinl 
395571f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
395671f87433Sdalcinl 
3957fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
395871f87433Sdalcinl @*/
39597087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
396071f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
396171f87433Sdalcinl {
3962fa9f3622SBarry Smith   SNESKSPEW *kctx;
396371f87433Sdalcinl   PetscFunctionBegin;
39640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3965fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
3966e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
396771f87433Sdalcinl   if(version)   *version   = kctx->version;
396871f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
396971f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
397071f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
397171f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
397271f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
397371f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
397471f87433Sdalcinl   PetscFunctionReturn(0);
397571f87433Sdalcinl }
397671f87433Sdalcinl 
397771f87433Sdalcinl #undef __FUNCT__
3978fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
3979fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
398071f87433Sdalcinl {
398171f87433Sdalcinl   PetscErrorCode ierr;
3982fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
398371f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
398471f87433Sdalcinl 
398571f87433Sdalcinl   PetscFunctionBegin;
3986e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
398771f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
398871f87433Sdalcinl     rtol = kctx->rtol_0;
398971f87433Sdalcinl   } else {
399071f87433Sdalcinl     if (kctx->version == 1) {
399171f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
399271f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
399371f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
399471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399571f87433Sdalcinl     } else if (kctx->version == 2) {
399671f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
399771f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
399871f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
399971f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
400071f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
400171f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
400271f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
400371f87433Sdalcinl       stol = PetscMax(rtol,stol);
400471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
400571f87433Sdalcinl       /* safeguard: avoid oversolving */
400671f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
400771f87433Sdalcinl       stol = PetscMax(rtol,stol);
400871f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4009e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
401071f87433Sdalcinl   }
401171f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
401271f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
401371f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
401471f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
401571f87433Sdalcinl   PetscFunctionReturn(0);
401671f87433Sdalcinl }
401771f87433Sdalcinl 
401871f87433Sdalcinl #undef __FUNCT__
4019fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4020fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
402171f87433Sdalcinl {
402271f87433Sdalcinl   PetscErrorCode ierr;
4023fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
402471f87433Sdalcinl   PCSide         pcside;
402571f87433Sdalcinl   Vec            lres;
402671f87433Sdalcinl 
402771f87433Sdalcinl   PetscFunctionBegin;
4028e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
402971f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
403071f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
403171f87433Sdalcinl   if (kctx->version == 1) {
4032b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
403371f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
403471f87433Sdalcinl       /* KSP residual is true linear residual */
403571f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
403671f87433Sdalcinl     } else {
403771f87433Sdalcinl       /* KSP residual is preconditioned residual */
403871f87433Sdalcinl       /* compute true linear residual norm */
403971f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
404071f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
404171f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
404271f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
40436bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
404471f87433Sdalcinl     }
404571f87433Sdalcinl   }
404671f87433Sdalcinl   PetscFunctionReturn(0);
404771f87433Sdalcinl }
404871f87433Sdalcinl 
404971f87433Sdalcinl #undef __FUNCT__
405071f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
405171f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
405271f87433Sdalcinl {
405371f87433Sdalcinl   PetscErrorCode ierr;
405471f87433Sdalcinl 
405571f87433Sdalcinl   PetscFunctionBegin;
4056fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
405771f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4058fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
405971f87433Sdalcinl   PetscFunctionReturn(0);
406071f87433Sdalcinl }
40616c699258SBarry Smith 
40626c699258SBarry Smith #undef __FUNCT__
40636c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
40646c699258SBarry Smith /*@
40656c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
40666c699258SBarry Smith 
40673f9fe445SBarry Smith    Logically Collective on SNES
40686c699258SBarry Smith 
40696c699258SBarry Smith    Input Parameters:
40706c699258SBarry Smith +  snes - the preconditioner context
40716c699258SBarry Smith -  dm - the dm
40726c699258SBarry Smith 
40736c699258SBarry Smith    Level: intermediate
40746c699258SBarry Smith 
40756c699258SBarry Smith 
40766c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
40776c699258SBarry Smith @*/
40787087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
40796c699258SBarry Smith {
40806c699258SBarry Smith   PetscErrorCode ierr;
4081345fed2cSBarry Smith   KSP            ksp;
40826cab3a1bSJed Brown   SNESDM         sdm;
40836c699258SBarry Smith 
40846c699258SBarry Smith   PetscFunctionBegin;
40850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4086d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
40876cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
40886cab3a1bSJed Brown     PetscContainer oldcontainer,container;
40896cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
40906cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
40916cab3a1bSJed Brown     if (oldcontainer && !container) {
40926cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
40936cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
40946cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
40956cab3a1bSJed Brown         sdm->originaldm = dm;
40966cab3a1bSJed Brown       }
40976cab3a1bSJed Brown     }
40986bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
40996cab3a1bSJed Brown   }
41006c699258SBarry Smith   snes->dm = dm;
4101345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4102345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4103f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
41042c155ee1SBarry Smith   if (snes->pc) {
41052c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
41062c155ee1SBarry Smith   }
41076c699258SBarry Smith   PetscFunctionReturn(0);
41086c699258SBarry Smith }
41096c699258SBarry Smith 
41106c699258SBarry Smith #undef __FUNCT__
41116c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
41126c699258SBarry Smith /*@
41136c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
41146c699258SBarry Smith 
41153f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
41166c699258SBarry Smith 
41176c699258SBarry Smith    Input Parameter:
41186c699258SBarry Smith . snes - the preconditioner context
41196c699258SBarry Smith 
41206c699258SBarry Smith    Output Parameter:
41216c699258SBarry Smith .  dm - the dm
41226c699258SBarry Smith 
41236c699258SBarry Smith    Level: intermediate
41246c699258SBarry Smith 
41256c699258SBarry Smith 
41266c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
41276c699258SBarry Smith @*/
41287087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
41296c699258SBarry Smith {
41306cab3a1bSJed Brown   PetscErrorCode ierr;
41316cab3a1bSJed Brown 
41326c699258SBarry Smith   PetscFunctionBegin;
41330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
41346cab3a1bSJed Brown   if (!snes->dm) {
41356cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
41366cab3a1bSJed Brown   }
41376c699258SBarry Smith   *dm = snes->dm;
41386c699258SBarry Smith   PetscFunctionReturn(0);
41396c699258SBarry Smith }
41400807856dSBarry Smith 
414131823bd8SMatthew G Knepley #undef __FUNCT__
414231823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
414331823bd8SMatthew G Knepley /*@
4144fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
414531823bd8SMatthew G Knepley 
414631823bd8SMatthew G Knepley   Collective on SNES
414731823bd8SMatthew G Knepley 
414831823bd8SMatthew G Knepley   Input Parameters:
414931823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
415031823bd8SMatthew G Knepley - pc   - the preconditioner object
415131823bd8SMatthew G Knepley 
415231823bd8SMatthew G Knepley   Notes:
415331823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
415431823bd8SMatthew G Knepley   to configure it using the API).
415531823bd8SMatthew G Knepley 
415631823bd8SMatthew G Knepley   Level: developer
415731823bd8SMatthew G Knepley 
415831823bd8SMatthew G Knepley .keywords: SNES, set, precondition
415931823bd8SMatthew G Knepley .seealso: SNESGetPC()
416031823bd8SMatthew G Knepley @*/
416131823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
416231823bd8SMatthew G Knepley {
416331823bd8SMatthew G Knepley   PetscErrorCode ierr;
416431823bd8SMatthew G Knepley 
416531823bd8SMatthew G Knepley   PetscFunctionBegin;
416631823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
416731823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
416831823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
416931823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4170bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
417131823bd8SMatthew G Knepley   snes->pc = pc;
417231823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
417331823bd8SMatthew G Knepley   PetscFunctionReturn(0);
417431823bd8SMatthew G Knepley }
417531823bd8SMatthew G Knepley 
417631823bd8SMatthew G Knepley #undef __FUNCT__
417731823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
417831823bd8SMatthew G Knepley /*@
4179fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
418031823bd8SMatthew G Knepley 
418131823bd8SMatthew G Knepley   Not Collective
418231823bd8SMatthew G Knepley 
418331823bd8SMatthew G Knepley   Input Parameter:
418431823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
418531823bd8SMatthew G Knepley 
418631823bd8SMatthew G Knepley   Output Parameter:
418731823bd8SMatthew G Knepley . pc - preconditioner context
418831823bd8SMatthew G Knepley 
418931823bd8SMatthew G Knepley   Level: developer
419031823bd8SMatthew G Knepley 
419131823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
419231823bd8SMatthew G Knepley .seealso: SNESSetPC()
419331823bd8SMatthew G Knepley @*/
419431823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
419531823bd8SMatthew G Knepley {
419631823bd8SMatthew G Knepley   PetscErrorCode ierr;
419731823bd8SMatthew G Knepley 
419831823bd8SMatthew G Knepley   PetscFunctionBegin;
419931823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
420031823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
420131823bd8SMatthew G Knepley   if (!snes->pc) {
420231823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
42034a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
420431823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
420531823bd8SMatthew G Knepley   }
420631823bd8SMatthew G Knepley   *pc = snes->pc;
420731823bd8SMatthew G Knepley   PetscFunctionReturn(0);
420831823bd8SMatthew G Knepley }
420931823bd8SMatthew G Knepley 
42109e764e56SPeter Brune #undef __FUNCT__
42119e764e56SPeter Brune #define __FUNCT__ "SNESSetPetscLineSearch"
42129e764e56SPeter Brune /*@
42139e764e56SPeter Brune   SNESSetPetscLineSearch - Sets the linesearch.
42149e764e56SPeter Brune 
42159e764e56SPeter Brune   Collective on SNES
42169e764e56SPeter Brune 
42179e764e56SPeter Brune   Input Parameters:
42189e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
42199e764e56SPeter Brune - linesearch   - the linesearch object
42209e764e56SPeter Brune 
42219e764e56SPeter Brune   Notes:
42229e764e56SPeter Brune   Use SNESGetPetscLineSearch() to retrieve the preconditioner context (for example,
42239e764e56SPeter Brune   to configure it using the API).
42249e764e56SPeter Brune 
42259e764e56SPeter Brune   Level: developer
42269e764e56SPeter Brune 
42279e764e56SPeter Brune .keywords: SNES, set, linesearch
4228*ea5d4fccSPeter Brune .seealso: SNESGetPetscLineSearch()
42299e764e56SPeter Brune @*/
42309e764e56SPeter Brune PetscErrorCode SNESSetPetscLineSearch(SNES snes, PetscLineSearch linesearch)
42319e764e56SPeter Brune {
42329e764e56SPeter Brune   PetscErrorCode ierr;
42339e764e56SPeter Brune 
42349e764e56SPeter Brune   PetscFunctionBegin;
42359e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42369e764e56SPeter Brune   PetscValidHeaderSpecific(linesearch, PETSCLINESEARCH_CLASSID, 2);
42379e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
42389e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
42399e764e56SPeter Brune   ierr = PetscLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
42409e764e56SPeter Brune   snes->linesearch = linesearch;
42419e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42429e764e56SPeter Brune   PetscFunctionReturn(0);
42439e764e56SPeter Brune }
42449e764e56SPeter Brune 
42459e764e56SPeter Brune #undef __FUNCT__
42469e764e56SPeter Brune #define __FUNCT__ "SNESGetPetscLineSearch"
4247*ea5d4fccSPeter Brune /*@C
42489e764e56SPeter Brune   SNESGetPetscLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch().
42499e764e56SPeter Brune 
42509e764e56SPeter Brune   Not Collective
42519e764e56SPeter Brune 
42529e764e56SPeter Brune   Input Parameter:
42539e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
42549e764e56SPeter Brune 
42559e764e56SPeter Brune   Output Parameter:
42569e764e56SPeter Brune . linesearch - linesearch context
42579e764e56SPeter Brune 
42589e764e56SPeter Brune   Level: developer
42599e764e56SPeter Brune 
42609e764e56SPeter Brune .keywords: SNES, get, linesearch
42619e764e56SPeter Brune .seealso: SNESSetPetscLineSearch()
42629e764e56SPeter Brune @*/
42639e764e56SPeter Brune PetscErrorCode SNESGetPetscLineSearch(SNES snes, PetscLineSearch *linesearch)
42649e764e56SPeter Brune {
42659e764e56SPeter Brune   PetscErrorCode ierr;
42669e764e56SPeter Brune   const char     *optionsprefix;
42679e764e56SPeter Brune 
42689e764e56SPeter Brune   PetscFunctionBegin;
42699e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
42709e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
42719e764e56SPeter Brune   if (!snes->linesearch) {
42729e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
42739e764e56SPeter Brune     ierr = PetscLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
42749e764e56SPeter Brune     ierr = PetscLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
42759e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
42769e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
42779e764e56SPeter Brune   }
42789e764e56SPeter Brune   *linesearch = snes->linesearch;
42799e764e56SPeter Brune   PetscFunctionReturn(0);
42809e764e56SPeter Brune }
42819e764e56SPeter Brune 
428269b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4283c6db04a5SJed Brown #include <mex.h>
428469b4f73cSBarry Smith 
42858f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
42868f6e6473SBarry Smith 
42870807856dSBarry Smith #undef __FUNCT__
42880807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
42890807856dSBarry Smith /*
42900807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
42910807856dSBarry Smith                          SNESSetFunctionMatlab().
42920807856dSBarry Smith 
42930807856dSBarry Smith    Collective on SNES
42940807856dSBarry Smith 
42950807856dSBarry Smith    Input Parameters:
42960807856dSBarry Smith +  snes - the SNES context
42970807856dSBarry Smith -  x - input vector
42980807856dSBarry Smith 
42990807856dSBarry Smith    Output Parameter:
43000807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
43010807856dSBarry Smith 
43020807856dSBarry Smith    Notes:
43030807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
43040807856dSBarry Smith    implementations, so most users would not generally call this routine
43050807856dSBarry Smith    themselves.
43060807856dSBarry Smith 
43070807856dSBarry Smith    Level: developer
43080807856dSBarry Smith 
43090807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
43100807856dSBarry Smith 
43110807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
431261b2408cSBarry Smith */
43137087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
43140807856dSBarry Smith {
4315e650e774SBarry Smith   PetscErrorCode    ierr;
43168f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
43178f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
43188f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
431991621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4320e650e774SBarry Smith 
43210807856dSBarry Smith   PetscFunctionBegin;
43220807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43230807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
43240807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
43250807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
43260807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
43270807856dSBarry Smith 
43280807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4329e650e774SBarry Smith 
433091621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4331e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4332e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
433391621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
433491621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
433591621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
43368f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
43378f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4338b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4339e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4340e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4341e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4342e650e774SBarry Smith   mxDestroyArray(prhs[2]);
43438f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4344e650e774SBarry Smith   mxDestroyArray(plhs[0]);
43450807856dSBarry Smith   PetscFunctionReturn(0);
43460807856dSBarry Smith }
43470807856dSBarry Smith 
43480807856dSBarry Smith 
43490807856dSBarry Smith #undef __FUNCT__
43500807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
435161b2408cSBarry Smith /*
43520807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
43530807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4354e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
43550807856dSBarry Smith 
43560807856dSBarry Smith    Logically Collective on SNES
43570807856dSBarry Smith 
43580807856dSBarry Smith    Input Parameters:
43590807856dSBarry Smith +  snes - the SNES context
43600807856dSBarry Smith .  r - vector to store function value
43610807856dSBarry Smith -  func - function evaluation routine
43620807856dSBarry Smith 
43630807856dSBarry Smith    Calling sequence of func:
436461b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
43650807856dSBarry Smith 
43660807856dSBarry Smith 
43670807856dSBarry Smith    Notes:
43680807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
43690807856dSBarry Smith $      f'(x) x = -f(x),
43700807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
43710807856dSBarry Smith 
43720807856dSBarry Smith    Level: beginner
43730807856dSBarry Smith 
43740807856dSBarry Smith .keywords: SNES, nonlinear, set, function
43750807856dSBarry Smith 
43760807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
437761b2408cSBarry Smith */
43787087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
43790807856dSBarry Smith {
43800807856dSBarry Smith   PetscErrorCode    ierr;
43818f6e6473SBarry Smith   SNESMatlabContext *sctx;
43820807856dSBarry Smith 
43830807856dSBarry Smith   PetscFunctionBegin;
43848f6e6473SBarry Smith   /* currently sctx is memory bleed */
43858f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
43868f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
43878f6e6473SBarry Smith   /*
43888f6e6473SBarry Smith      This should work, but it doesn't
43898f6e6473SBarry Smith   sctx->ctx = ctx;
43908f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
43918f6e6473SBarry Smith   */
43928f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
43938f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
43940807856dSBarry Smith   PetscFunctionReturn(0);
43950807856dSBarry Smith }
439669b4f73cSBarry Smith 
439761b2408cSBarry Smith #undef __FUNCT__
439861b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
439961b2408cSBarry Smith /*
440061b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
440161b2408cSBarry Smith                          SNESSetJacobianMatlab().
440261b2408cSBarry Smith 
440361b2408cSBarry Smith    Collective on SNES
440461b2408cSBarry Smith 
440561b2408cSBarry Smith    Input Parameters:
440661b2408cSBarry Smith +  snes - the SNES context
440761b2408cSBarry Smith .  x - input vector
440861b2408cSBarry Smith .  A, B - the matrices
440961b2408cSBarry Smith -  ctx - user context
441061b2408cSBarry Smith 
441161b2408cSBarry Smith    Output Parameter:
441261b2408cSBarry Smith .  flag - structure of the matrix
441361b2408cSBarry Smith 
441461b2408cSBarry Smith    Level: developer
441561b2408cSBarry Smith 
441661b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
441761b2408cSBarry Smith 
441861b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
441961b2408cSBarry Smith @*/
44207087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
442161b2408cSBarry Smith {
442261b2408cSBarry Smith   PetscErrorCode    ierr;
442361b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
442461b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
442561b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
442661b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
442761b2408cSBarry Smith 
442861b2408cSBarry Smith   PetscFunctionBegin;
442961b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
443061b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
443161b2408cSBarry Smith 
443261b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
443361b2408cSBarry Smith 
443461b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
443561b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
443661b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
443761b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
443861b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
443961b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
444061b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
444161b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
444261b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
444361b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4444b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
444561b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
444661b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
444761b2408cSBarry Smith   mxDestroyArray(prhs[0]);
444861b2408cSBarry Smith   mxDestroyArray(prhs[1]);
444961b2408cSBarry Smith   mxDestroyArray(prhs[2]);
445061b2408cSBarry Smith   mxDestroyArray(prhs[3]);
445161b2408cSBarry Smith   mxDestroyArray(prhs[4]);
445261b2408cSBarry Smith   mxDestroyArray(plhs[0]);
445361b2408cSBarry Smith   mxDestroyArray(plhs[1]);
445461b2408cSBarry Smith   PetscFunctionReturn(0);
445561b2408cSBarry Smith }
445661b2408cSBarry Smith 
445761b2408cSBarry Smith 
445861b2408cSBarry Smith #undef __FUNCT__
445961b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
446061b2408cSBarry Smith /*
446161b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
446261b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4463e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
446461b2408cSBarry Smith 
446561b2408cSBarry Smith    Logically Collective on SNES
446661b2408cSBarry Smith 
446761b2408cSBarry Smith    Input Parameters:
446861b2408cSBarry Smith +  snes - the SNES context
446961b2408cSBarry Smith .  A,B - Jacobian matrices
447061b2408cSBarry Smith .  func - function evaluation routine
447161b2408cSBarry Smith -  ctx - user context
447261b2408cSBarry Smith 
447361b2408cSBarry Smith    Calling sequence of func:
447461b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
447561b2408cSBarry Smith 
447661b2408cSBarry Smith 
447761b2408cSBarry Smith    Level: developer
447861b2408cSBarry Smith 
447961b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
448061b2408cSBarry Smith 
448161b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
448261b2408cSBarry Smith */
44837087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
448461b2408cSBarry Smith {
448561b2408cSBarry Smith   PetscErrorCode    ierr;
448661b2408cSBarry Smith   SNESMatlabContext *sctx;
448761b2408cSBarry Smith 
448861b2408cSBarry Smith   PetscFunctionBegin;
448961b2408cSBarry Smith   /* currently sctx is memory bleed */
449061b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
449161b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
449261b2408cSBarry Smith   /*
449361b2408cSBarry Smith      This should work, but it doesn't
449461b2408cSBarry Smith   sctx->ctx = ctx;
449561b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
449661b2408cSBarry Smith   */
449761b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
449861b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
449961b2408cSBarry Smith   PetscFunctionReturn(0);
450061b2408cSBarry Smith }
450169b4f73cSBarry Smith 
4502f9eb7ae2SShri Abhyankar #undef __FUNCT__
4503f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4504f9eb7ae2SShri Abhyankar /*
4505f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4506f9eb7ae2SShri Abhyankar 
4507f9eb7ae2SShri Abhyankar    Collective on SNES
4508f9eb7ae2SShri Abhyankar 
4509f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4510f9eb7ae2SShri Abhyankar @*/
45117087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4512f9eb7ae2SShri Abhyankar {
4513f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
451448f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4515f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4516f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4517f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4518f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4519f9eb7ae2SShri Abhyankar 
4520f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4521f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4522f9eb7ae2SShri Abhyankar 
4523f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4524f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4525f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4526f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4527f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4528f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4529f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4530f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4531f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4532f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4533f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4534f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4535f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4536f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4537f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4538f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4539f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4540f9eb7ae2SShri Abhyankar }
4541f9eb7ae2SShri Abhyankar 
4542f9eb7ae2SShri Abhyankar 
4543f9eb7ae2SShri Abhyankar #undef __FUNCT__
4544f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4545f9eb7ae2SShri Abhyankar /*
4546e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4547f9eb7ae2SShri Abhyankar 
4548f9eb7ae2SShri Abhyankar    Level: developer
4549f9eb7ae2SShri Abhyankar 
4550f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4551f9eb7ae2SShri Abhyankar 
4552f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4553f9eb7ae2SShri Abhyankar */
45547087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4555f9eb7ae2SShri Abhyankar {
4556f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4557f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4558f9eb7ae2SShri Abhyankar 
4559f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4560f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4561f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4562f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4563f9eb7ae2SShri Abhyankar   /*
4564f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4565f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4566f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4567f9eb7ae2SShri Abhyankar   */
4568f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4569f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4570f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4571f9eb7ae2SShri Abhyankar }
4572f9eb7ae2SShri Abhyankar 
457369b4f73cSBarry Smith #endif
4574