xref: /petsc/src/snes/interface/snes.c (revision ecaffdda287f357c8fe4ab0cb82a0c64d6671904)
19b94acceSBarry Smith 
2b45d2f2cSJed Brown #include <petsc-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;
10f1c6b773SPeter Brune PetscLogEvent  SNES_Solve, SNES_FunctionEval, SNES_JacobianEval, SNES_GSEval;
11a09944afSBarry Smith 
12a09944afSBarry Smith #undef __FUNCT__
13e113a28aSBarry Smith #define __FUNCT__ "SNESSetErrorIfNotConverged"
14e113a28aSBarry Smith /*@
15e113a28aSBarry Smith    SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
16e113a28aSBarry Smith 
173f9fe445SBarry Smith    Logically Collective on SNES
18e113a28aSBarry Smith 
19e113a28aSBarry Smith    Input Parameters:
20e113a28aSBarry Smith +  snes - iterative context obtained from SNESCreate()
21e113a28aSBarry Smith -  flg - PETSC_TRUE indicates you want the error generated
22e113a28aSBarry Smith 
23e113a28aSBarry Smith    Options database keys:
24e113a28aSBarry Smith .  -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
25e113a28aSBarry Smith 
26e113a28aSBarry Smith    Level: intermediate
27e113a28aSBarry Smith 
28e113a28aSBarry Smith    Notes:
29e113a28aSBarry Smith     Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
30e113a28aSBarry Smith     to determine if it has converged.
31e113a28aSBarry Smith 
32e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
33e113a28aSBarry Smith 
34e113a28aSBarry Smith .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
35e113a28aSBarry Smith @*/
367087cfbeSBarry Smith PetscErrorCode  SNESSetErrorIfNotConverged(SNES snes,PetscBool  flg)
37e113a28aSBarry Smith {
38e113a28aSBarry Smith   PetscFunctionBegin;
39e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
40acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flg,2);
41e113a28aSBarry Smith   snes->errorifnotconverged = flg;
42dd568438SSatish Balay 
43e113a28aSBarry Smith   PetscFunctionReturn(0);
44e113a28aSBarry Smith }
45e113a28aSBarry Smith 
46e113a28aSBarry Smith #undef __FUNCT__
47e113a28aSBarry Smith #define __FUNCT__ "SNESGetErrorIfNotConverged"
48e113a28aSBarry Smith /*@
49e113a28aSBarry Smith    SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
50e113a28aSBarry Smith 
51e113a28aSBarry Smith    Not Collective
52e113a28aSBarry Smith 
53e113a28aSBarry Smith    Input Parameter:
54e113a28aSBarry Smith .  snes - iterative context obtained from SNESCreate()
55e113a28aSBarry Smith 
56e113a28aSBarry Smith    Output Parameter:
57e113a28aSBarry Smith .  flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
58e113a28aSBarry Smith 
59e113a28aSBarry Smith    Level: intermediate
60e113a28aSBarry Smith 
61e113a28aSBarry Smith .keywords: SNES, set, initial guess, nonzero
62e113a28aSBarry Smith 
63e113a28aSBarry Smith .seealso:  SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
64e113a28aSBarry Smith @*/
657087cfbeSBarry Smith PetscErrorCode  SNESGetErrorIfNotConverged(SNES snes,PetscBool  *flag)
66e113a28aSBarry Smith {
67e113a28aSBarry Smith   PetscFunctionBegin;
68e113a28aSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
69e113a28aSBarry Smith   PetscValidPointer(flag,2);
70e113a28aSBarry Smith   *flag = snes->errorifnotconverged;
71e113a28aSBarry Smith   PetscFunctionReturn(0);
72e113a28aSBarry Smith }
73e113a28aSBarry Smith 
74e113a28aSBarry Smith #undef __FUNCT__
754936397dSBarry Smith #define __FUNCT__ "SNESSetFunctionDomainError"
76e725d27bSBarry Smith /*@
774936397dSBarry Smith    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
784936397dSBarry Smith      in the functions domain. For example, negative pressure.
794936397dSBarry Smith 
803f9fe445SBarry Smith    Logically Collective on SNES
814936397dSBarry Smith 
824936397dSBarry Smith    Input Parameters:
836a388c36SPeter Brune .  snes - the SNES context
844936397dSBarry Smith 
8528529972SSatish Balay    Level: advanced
864936397dSBarry Smith 
874936397dSBarry Smith .keywords: SNES, view
884936397dSBarry Smith 
894936397dSBarry Smith .seealso: SNESCreate(), SNESSetFunction()
904936397dSBarry Smith @*/
917087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
924936397dSBarry Smith {
934936397dSBarry Smith   PetscFunctionBegin;
940700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
954936397dSBarry Smith   snes->domainerror = PETSC_TRUE;
964936397dSBarry Smith   PetscFunctionReturn(0);
974936397dSBarry Smith }
984936397dSBarry Smith 
996a388c36SPeter Brune 
1006a388c36SPeter Brune #undef __FUNCT__
1016a388c36SPeter Brune #define __FUNCT__ "SNESGetFunctionDomainError"
1026a388c36SPeter Brune /*@
103c77b2880SPeter Brune    SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction;
1046a388c36SPeter Brune 
1056a388c36SPeter Brune    Logically Collective on SNES
1066a388c36SPeter Brune 
1076a388c36SPeter Brune    Input Parameters:
1086a388c36SPeter Brune .  snes - the SNES context
1096a388c36SPeter Brune 
1106a388c36SPeter Brune    Output Parameters:
1116a388c36SPeter Brune .  domainerror Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise.
1126a388c36SPeter Brune 
1136a388c36SPeter Brune    Level: advanced
1146a388c36SPeter Brune 
1156a388c36SPeter Brune .keywords: SNES, view
1166a388c36SPeter Brune 
1176a388c36SPeter Brune .seealso: SNESSetFunctionDomainError, SNESComputeFunction()
1186a388c36SPeter Brune @*/
1196a388c36SPeter Brune PetscErrorCode  SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror)
1206a388c36SPeter Brune {
1216a388c36SPeter Brune   PetscFunctionBegin;
1226a388c36SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1236a388c36SPeter Brune   PetscValidPointer(domainerror, 2);
1246a388c36SPeter Brune   *domainerror = snes->domainerror;
1256a388c36SPeter Brune   PetscFunctionReturn(0);
1266a388c36SPeter Brune }
1276a388c36SPeter Brune 
1286a388c36SPeter Brune 
1294936397dSBarry Smith #undef __FUNCT__
1304a2ae208SSatish Balay #define __FUNCT__ "SNESView"
1317e2c5f70SBarry Smith /*@C
1329b94acceSBarry Smith    SNESView - Prints the SNES data structure.
1339b94acceSBarry Smith 
1344c49b128SBarry Smith    Collective on SNES
135fee21e36SBarry Smith 
136c7afd0dbSLois Curfman McInnes    Input Parameters:
137c7afd0dbSLois Curfman McInnes +  SNES - the SNES context
138c7afd0dbSLois Curfman McInnes -  viewer - visualization context
139c7afd0dbSLois Curfman McInnes 
1409b94acceSBarry Smith    Options Database Key:
141c8a8ba5cSLois Curfman McInnes .  -snes_view - Calls SNESView() at end of SNESSolve()
1429b94acceSBarry Smith 
1439b94acceSBarry Smith    Notes:
1449b94acceSBarry Smith    The available visualization contexts include
145b0a32e0cSBarry Smith +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
146b0a32e0cSBarry Smith -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
147c8a8ba5cSLois Curfman McInnes          output where only the first processor opens
148c8a8ba5cSLois Curfman McInnes          the file.  All other processors send their
149c8a8ba5cSLois Curfman McInnes          data to the first processor to print.
1509b94acceSBarry Smith 
1513e081fefSLois Curfman McInnes    The user can open an alternative visualization context with
152b0a32e0cSBarry Smith    PetscViewerASCIIOpen() - output to a specified file.
1539b94acceSBarry Smith 
15436851e7fSLois Curfman McInnes    Level: beginner
15536851e7fSLois Curfman McInnes 
1569b94acceSBarry Smith .keywords: SNES, view
1579b94acceSBarry Smith 
158b0a32e0cSBarry Smith .seealso: PetscViewerASCIIOpen()
1599b94acceSBarry Smith @*/
1607087cfbeSBarry Smith PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
1619b94acceSBarry Smith {
162fa9f3622SBarry Smith   SNESKSPEW           *kctx;
163dfbe8321SBarry Smith   PetscErrorCode      ierr;
16494b7f48cSBarry Smith   KSP                 ksp;
1657f1410a3SPeter Brune   SNESLineSearch      linesearch;
166ace3abfcSBarry Smith   PetscBool           iascii,isstring;
1679b94acceSBarry Smith 
1683a40ed3dSBarry Smith   PetscFunctionBegin;
1690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1703050cee2SBarry Smith   if (!viewer) {
1717adad957SLisandro Dalcin     ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
1723050cee2SBarry Smith   }
1730700a824SBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
174c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,viewer,2);
17574679c65SBarry Smith 
176251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
177251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
17832077d6dSBarry Smith   if (iascii) {
179317d6ea6SBarry Smith     ierr = PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");CHKERRQ(ierr);
180e7788613SBarry Smith     if (snes->ops->view) {
181b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
182e7788613SBarry Smith       ierr = (*snes->ops->view)(snes,viewer);CHKERRQ(ierr);
183b0a32e0cSBarry Smith       ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
1840ef38995SBarry Smith     }
18577431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);CHKERRQ(ierr);
186a83599f4SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
187c60f73f4SPeter Brune                  snes->rtol,snes->abstol,snes->stol);CHKERRQ(ierr);
18877431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);CHKERRQ(ierr);
18977431f27SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);CHKERRQ(ierr);
1909b94acceSBarry Smith     if (snes->ksp_ewconv) {
191fa9f3622SBarry Smith       kctx = (SNESKSPEW *)snes->kspconvctx;
1929b94acceSBarry Smith       if (kctx) {
19377431f27SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);CHKERRQ(ierr);
194a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);CHKERRQ(ierr);
195a83599f4SBarry Smith         ierr = PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);CHKERRQ(ierr);
1969b94acceSBarry Smith       }
1979b94acceSBarry Smith     }
198eb1f6c34SBarry Smith     if (snes->lagpreconditioner == -1) {
199eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is never rebuilt\n");CHKERRQ(ierr);
200eb1f6c34SBarry Smith     } else if (snes->lagpreconditioner > 1) {
201eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);CHKERRQ(ierr);
202eb1f6c34SBarry Smith     }
203eb1f6c34SBarry Smith     if (snes->lagjacobian == -1) {
204eb1f6c34SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is never rebuilt\n");CHKERRQ(ierr);
205eb1f6c34SBarry Smith     } else if (snes->lagjacobian > 1) {
20642f4f86dSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Jacobian is rebuilt every %D SNES iterations\n",snes->lagjacobian);CHKERRQ(ierr);
207eb1f6c34SBarry Smith     }
2080f5bd95cSBarry Smith   } else if (isstring) {
209317d6ea6SBarry Smith     const char *type;
210454a90a3SBarry Smith     ierr = SNESGetType(snes,&type);CHKERRQ(ierr);
211b0a32e0cSBarry Smith     ierr = PetscViewerStringSPrintf(viewer," %-3.3s",type);CHKERRQ(ierr);
21219bcc07fSBarry Smith   }
21342f4f86dSBarry Smith   if (snes->pc && snes->usespc) {
2144a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2154a0c5b0cSMatthew G Knepley     ierr = SNESView(snes->pc, viewer);CHKERRQ(ierr);
2164a0c5b0cSMatthew G Knepley     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2174a0c5b0cSMatthew G Knepley   }
2182c155ee1SBarry Smith   if (snes->usesksp) {
2192c155ee1SBarry Smith     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
220b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
22194b7f48cSBarry Smith     ierr = KSPView(ksp,viewer);CHKERRQ(ierr);
222b0a32e0cSBarry Smith     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2232c155ee1SBarry Smith   }
2247f1410a3SPeter Brune   if (snes->linesearch) {
2257f1410a3SPeter Brune     ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr);
2267f1410a3SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &linesearch);CHKERRQ(ierr);
2277f1410a3SPeter Brune     ierr = SNESLineSearchView(linesearch, viewer);CHKERRQ(ierr);
2287f1410a3SPeter Brune     ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr);
2297f1410a3SPeter Brune   }
2303a40ed3dSBarry Smith   PetscFunctionReturn(0);
2319b94acceSBarry Smith }
2329b94acceSBarry Smith 
23376b2cf59SMatthew Knepley /*
23476b2cf59SMatthew Knepley   We retain a list of functions that also take SNES command
23576b2cf59SMatthew Knepley   line options. These are called at the end SNESSetFromOptions()
23676b2cf59SMatthew Knepley */
23776b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5
238a7cc72afSBarry Smith static PetscInt numberofsetfromoptions;
2396849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
24076b2cf59SMatthew Knepley 
241e74ef692SMatthew Knepley #undef __FUNCT__
242e74ef692SMatthew Knepley #define __FUNCT__ "SNESAddOptionsChecker"
243ac226902SBarry Smith /*@C
24476b2cf59SMatthew Knepley   SNESAddOptionsChecker - Adds an additional function to check for SNES options.
24576b2cf59SMatthew Knepley 
24676b2cf59SMatthew Knepley   Not Collective
24776b2cf59SMatthew Knepley 
24876b2cf59SMatthew Knepley   Input Parameter:
24976b2cf59SMatthew Knepley . snescheck - function that checks for options
25076b2cf59SMatthew Knepley 
25176b2cf59SMatthew Knepley   Level: developer
25276b2cf59SMatthew Knepley 
25376b2cf59SMatthew Knepley .seealso: SNESSetFromOptions()
25476b2cf59SMatthew Knepley @*/
2557087cfbeSBarry Smith PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
25676b2cf59SMatthew Knepley {
25776b2cf59SMatthew Knepley   PetscFunctionBegin;
25876b2cf59SMatthew Knepley   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
259e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
26076b2cf59SMatthew Knepley   }
26176b2cf59SMatthew Knepley   othersetfromoptions[numberofsetfromoptions++] = snescheck;
26276b2cf59SMatthew Knepley   PetscFunctionReturn(0);
26376b2cf59SMatthew Knepley }
26476b2cf59SMatthew Knepley 
2657087cfbeSBarry Smith extern PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
266aa3661deSLisandro Dalcin 
267aa3661deSLisandro Dalcin #undef __FUNCT__
268aa3661deSLisandro Dalcin #define __FUNCT__ "SNESSetUpMatrixFree_Private"
269ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool  hasOperator, PetscInt version)
270aa3661deSLisandro Dalcin {
271aa3661deSLisandro Dalcin   Mat            J;
272aa3661deSLisandro Dalcin   KSP            ksp;
273aa3661deSLisandro Dalcin   PC             pc;
274ace3abfcSBarry Smith   PetscBool      match;
275aa3661deSLisandro Dalcin   PetscErrorCode ierr;
276aa3661deSLisandro Dalcin 
277aa3661deSLisandro Dalcin   PetscFunctionBegin;
2780700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
279aa3661deSLisandro Dalcin 
28098613b67SLisandro Dalcin   if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
28198613b67SLisandro Dalcin     Mat A = snes->jacobian, B = snes->jacobian_pre;
28298613b67SLisandro Dalcin     ierr = MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);CHKERRQ(ierr);
28398613b67SLisandro Dalcin   }
28498613b67SLisandro Dalcin 
285aa3661deSLisandro Dalcin   if (version == 1) {
286aa3661deSLisandro Dalcin     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
28798613b67SLisandro Dalcin     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
2889c6ac3b3SBarry Smith     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
289aa3661deSLisandro Dalcin   } else if (version == 2) {
290e32f2f54SBarry Smith     if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
29182a7e548SBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128)
292aa3661deSLisandro Dalcin     ierr = SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);CHKERRQ(ierr);
293aa3661deSLisandro Dalcin #else
294e32f2f54SBarry Smith     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
295aa3661deSLisandro Dalcin #endif
296a8248277SBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
297aa3661deSLisandro Dalcin 
298aa3661deSLisandro Dalcin   ierr = PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);CHKERRQ(ierr);
299d3462f78SMatthew Knepley   if (hasOperator) {
300aa3661deSLisandro Dalcin     /* This version replaces the user provided Jacobian matrix with a
301aa3661deSLisandro Dalcin        matrix-free version but still employs the user-provided preconditioner matrix. */
302aa3661deSLisandro Dalcin     ierr = SNESSetJacobian(snes,J,0,0,0);CHKERRQ(ierr);
303aa3661deSLisandro Dalcin   } else {
304aa3661deSLisandro Dalcin     /* This version replaces both the user-provided Jacobian and the user-
305aa3661deSLisandro Dalcin        provided preconditioner matrix with the default matrix free version. */
3066cab3a1bSJed Brown     void *functx;
3076cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
3086cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
309aa3661deSLisandro Dalcin     /* Force no preconditioner */
310aa3661deSLisandro Dalcin     ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
311aa3661deSLisandro Dalcin     ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
312251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)pc,PCSHELL,&match);CHKERRQ(ierr);
313aa3661deSLisandro Dalcin     if (!match) {
314aa3661deSLisandro Dalcin       ierr = PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");CHKERRQ(ierr);
315aa3661deSLisandro Dalcin       ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr);
316aa3661deSLisandro Dalcin     }
317aa3661deSLisandro Dalcin   }
3186bf464f9SBarry Smith   ierr = MatDestroy(&J);CHKERRQ(ierr);
319aa3661deSLisandro Dalcin   PetscFunctionReturn(0);
320aa3661deSLisandro Dalcin }
321aa3661deSLisandro Dalcin 
3224a2ae208SSatish Balay #undef __FUNCT__
323dfe15315SJed Brown #define __FUNCT__ "DMRestrictHook_SNESVecSol"
324dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx)
325dfe15315SJed Brown {
326dfe15315SJed Brown   SNES snes = (SNES)ctx;
327dfe15315SJed Brown   PetscErrorCode ierr;
328dfe15315SJed Brown   Vec Xfine,Xfine_named = PETSC_NULL,Xcoarse;
329dfe15315SJed Brown 
330dfe15315SJed Brown   PetscFunctionBegin;
331dfe15315SJed Brown   if (dmfine == snes->dm) Xfine = snes->vec_sol;
332dfe15315SJed Brown   else {
333dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);
334dfe15315SJed Brown     Xfine = Xfine_named;
335dfe15315SJed Brown   }
336dfe15315SJed Brown   ierr = DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
337dfe15315SJed Brown   ierr = MatRestrict(Restrict,Xfine,Xcoarse);CHKERRQ(ierr);
338dfe15315SJed Brown   ierr = VecPointwiseMult(Xcoarse,Xcoarse,Rscale);CHKERRQ(ierr);
339dfe15315SJed Brown   ierr = DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse);CHKERRQ(ierr);
340dfe15315SJed Brown   if (Xfine_named) {ierr = DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named);CHKERRQ(ierr);}
341dfe15315SJed Brown   PetscFunctionReturn(0);
342dfe15315SJed Brown }
343dfe15315SJed Brown 
344dfe15315SJed Brown #undef __FUNCT__
345caa4e7f2SJed Brown #define __FUNCT__ "KSPComputeOperators_SNES"
346a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can
347a6950cb2SJed Brown  * safely call SNESGetDM() in their residual evaluation routine. */
348caa4e7f2SJed Brown static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,MatStructure *mstruct,void *ctx)
349caa4e7f2SJed Brown {
350caa4e7f2SJed Brown   SNES snes = (SNES)ctx;
351caa4e7f2SJed Brown   PetscErrorCode ierr;
352caa4e7f2SJed Brown   Mat Asave = A,Bsave = B;
353dfe15315SJed Brown   Vec X,Xnamed = PETSC_NULL;
354dfe15315SJed Brown   DM dmsave;
355caa4e7f2SJed Brown 
356caa4e7f2SJed Brown   PetscFunctionBegin;
357dfe15315SJed Brown   dmsave = snes->dm;
358dfe15315SJed Brown   ierr = KSPGetDM(ksp,&snes->dm);CHKERRQ(ierr);
359dfe15315SJed Brown   if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */
360dfe15315SJed Brown   else {                                     /* We are on a coarser level, this vec was initialized using a DM restrict hook */
361dfe15315SJed Brown     ierr = DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
362dfe15315SJed Brown     X = Xnamed;
363dfe15315SJed Brown   }
364dfe15315SJed Brown   ierr = SNESComputeJacobian(snes,X,&A,&B,mstruct);CHKERRQ(ierr);
365caa4e7f2SJed Brown   if (A != Asave || B != Bsave) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_SUP,"No support for changing matrices at this time");
366dfe15315SJed Brown   if (Xnamed) {
367dfe15315SJed Brown     ierr = DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed);CHKERRQ(ierr);
368dfe15315SJed Brown   }
369dfe15315SJed Brown   snes->dm = dmsave;
370caa4e7f2SJed Brown   PetscFunctionReturn(0);
371caa4e7f2SJed Brown }
372caa4e7f2SJed Brown 
373caa4e7f2SJed Brown #undef __FUNCT__
3746cab3a1bSJed Brown #define __FUNCT__ "SNESSetUpMatrices"
3756cab3a1bSJed Brown /*@
3766cab3a1bSJed Brown    SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX()
3776cab3a1bSJed Brown 
3786cab3a1bSJed Brown    Collective
3796cab3a1bSJed Brown 
3806cab3a1bSJed Brown    Input Arguments:
3816cab3a1bSJed Brown .  snes - snes to configure
3826cab3a1bSJed Brown 
3836cab3a1bSJed Brown    Level: developer
3846cab3a1bSJed Brown 
3856cab3a1bSJed Brown .seealso: SNESSetUp()
3866cab3a1bSJed Brown @*/
3876cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes)
3886cab3a1bSJed Brown {
3896cab3a1bSJed Brown   PetscErrorCode ierr;
3906cab3a1bSJed Brown   DM             dm;
3916cab3a1bSJed Brown   SNESDM         sdm;
3926cab3a1bSJed Brown 
3936cab3a1bSJed Brown   PetscFunctionBegin;
3946cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3956cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
396caa4e7f2SJed Brown   if (!sdm->computejacobian) {
3976cab3a1bSJed Brown     Mat J,B;
3986cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
3996cab3a1bSJed Brown     if (snes->mf_operator) {
4006cab3a1bSJed Brown       ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4016cab3a1bSJed Brown       ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4026cab3a1bSJed Brown       ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4036cab3a1bSJed Brown     } else {
4046cab3a1bSJed Brown       J = B;
4056cab3a1bSJed Brown       ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
4066cab3a1bSJed Brown     }
4076cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,PETSC_NULL);CHKERRQ(ierr);
4086cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4096cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4106cab3a1bSJed Brown   } else if (!snes->jacobian && sdm->computejacobian == MatMFFDComputeJacobian) {
4116cab3a1bSJed Brown     Mat J;
4126cab3a1bSJed Brown     void *functx;
4136cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4146cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4156cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4166cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4176cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,functx);CHKERRQ(ierr);
4186cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
419caa4e7f2SJed Brown   } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
4206cab3a1bSJed Brown     Mat J,B;
4216cab3a1bSJed Brown     void *functx;
4226cab3a1bSJed Brown     ierr = MatCreateSNESMF(snes,&J);CHKERRQ(ierr);
4236cab3a1bSJed Brown     ierr = MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);CHKERRQ(ierr);
4246cab3a1bSJed Brown     ierr = MatSetFromOptions(J);CHKERRQ(ierr);
4256cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4266cab3a1bSJed Brown     ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
4276cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,functx);CHKERRQ(ierr);
4286cab3a1bSJed Brown     ierr = MatDestroy(&J);CHKERRQ(ierr);
4296cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
430caa4e7f2SJed Brown   } else if (!snes->jacobian_pre) {
4316cab3a1bSJed Brown     Mat J,B;
4326cab3a1bSJed Brown     J = snes->jacobian;
4336cab3a1bSJed Brown     ierr = DMCreateMatrix(snes->dm,MATAIJ,&B);CHKERRQ(ierr);
4346cab3a1bSJed Brown     ierr = SNESSetJacobian(snes,J?J:B,B,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
4356cab3a1bSJed Brown     ierr = MatDestroy(&B);CHKERRQ(ierr);
4366cab3a1bSJed Brown   }
437caa4e7f2SJed Brown   {
43860a3618bSJed Brown     PetscBool flg = PETSC_FALSE;
439caa4e7f2SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_kspcompute",&flg,PETSC_NULL);CHKERRQ(ierr);
440caa4e7f2SJed Brown     if (flg) {                  /* Plan to transition to this model */
441caa4e7f2SJed Brown       KSP ksp;
442caa4e7f2SJed Brown       ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
443caa4e7f2SJed Brown       ierr = KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes);CHKERRQ(ierr);
444dfe15315SJed Brown       ierr = DMCoarsenHookAdd(snes->dm,PETSC_NULL,DMRestrictHook_SNESVecSol,snes);CHKERRQ(ierr);
445caa4e7f2SJed Brown     }
446caa4e7f2SJed Brown   }
4476cab3a1bSJed Brown   PetscFunctionReturn(0);
4486cab3a1bSJed Brown }
4496cab3a1bSJed Brown 
4506cab3a1bSJed Brown #undef __FUNCT__
4514a2ae208SSatish Balay #define __FUNCT__ "SNESSetFromOptions"
4529b94acceSBarry Smith /*@
45394b7f48cSBarry Smith    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
4549b94acceSBarry Smith 
455c7afd0dbSLois Curfman McInnes    Collective on SNES
456c7afd0dbSLois Curfman McInnes 
4579b94acceSBarry Smith    Input Parameter:
4589b94acceSBarry Smith .  snes - the SNES context
4599b94acceSBarry Smith 
46036851e7fSLois Curfman McInnes    Options Database Keys:
461ea630c6eSPeter Brune +  -snes_type <type> - ls, tr, ngmres, ncg, richardson, qn, vi, fas
46282738288SBarry Smith .  -snes_stol - convergence tolerance in terms of the norm
46382738288SBarry Smith                 of the change in the solution between steps
46470441072SBarry Smith .  -snes_atol <abstol> - absolute tolerance of residual norm
465b39c3a46SLois Curfman McInnes .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
466b39c3a46SLois Curfman McInnes .  -snes_max_it <max_it> - maximum number of iterations
467b39c3a46SLois Curfman McInnes .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
4684839bfe8SBarry Smith .  -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none
469ddf469c8SBarry Smith .  -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
470a8054027SBarry Smith .  -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
471e35cf81dSBarry Smith .  -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
472b39c3a46SLois Curfman McInnes .  -snes_trtol <trtol> - trust region tolerance
4732492ecdbSBarry Smith .  -snes_no_convergence_test - skip convergence test in nonlinear
47482738288SBarry Smith                                solver; hence iterations will continue until max_it
4751fbbfb26SLois Curfman McInnes                                or some other criterion is reached. Saves expense
47682738288SBarry Smith                                of convergence test
477e8105e01SRichard Katz .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
478e8105e01SRichard Katz                                        filename given prints to stdout
479a6570f20SBarry Smith .  -snes_monitor_solution - plots solution at each iteration
480a6570f20SBarry Smith .  -snes_monitor_residual - plots residual (not its norm) at each iteration
481a6570f20SBarry Smith .  -snes_monitor_solution_update - plots update to solution at each iteration
482a6570f20SBarry Smith .  -snes_monitor_draw - plots residual norm at each iteration
483e24b481bSBarry Smith .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
4845968eb51SBarry Smith .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
485fee2055bSBarry Smith -  -snes_converged_reason - print the reason for convergence/divergence after each solve
48682738288SBarry Smith 
48782738288SBarry Smith     Options Database for Eisenstat-Walker method:
488fa9f3622SBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
4894b27c08aSLois Curfman McInnes .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
49036851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
49136851e7fSLois Curfman McInnes .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
49236851e7fSLois Curfman McInnes .  -snes_ksp_ew_gamma <gamma> - Sets gamma
49336851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha <alpha> - Sets alpha
49436851e7fSLois Curfman McInnes .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
49536851e7fSLois Curfman McInnes -  -snes_ksp_ew_threshold <threshold> - Sets threshold
49682738288SBarry Smith 
49711ca99fdSLois Curfman McInnes    Notes:
49811ca99fdSLois Curfman McInnes    To see all options, run your program with the -help option or consult
4990598bfebSBarry Smith    the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
50083e2fdc7SBarry Smith 
50136851e7fSLois Curfman McInnes    Level: beginner
50236851e7fSLois Curfman McInnes 
5039b94acceSBarry Smith .keywords: SNES, nonlinear, set, options, database
5049b94acceSBarry Smith 
50569ed319cSSatish Balay .seealso: SNESSetOptionsPrefix()
5069b94acceSBarry Smith @*/
5077087cfbeSBarry Smith PetscErrorCode  SNESSetFromOptions(SNES snes)
5089b94acceSBarry Smith {
509872b6db9SPeter Brune   PetscBool               flg,mf,mf_operator,pcset;
510efd51863SBarry Smith   PetscInt                i,indx,lag,mf_version,grids;
511aa3661deSLisandro Dalcin   MatStructure            matflag;
51285385478SLisandro Dalcin   const char              *deft = SNESLS;
51385385478SLisandro Dalcin   const char              *convtests[] = {"default","skip"};
51485385478SLisandro Dalcin   SNESKSPEW               *kctx = NULL;
515e8105e01SRichard Katz   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
51651e86f29SPeter Brune   const char              *optionsprefix;
517649052a6SBarry Smith   PetscViewer             monviewer;
51885385478SLisandro Dalcin   PetscErrorCode          ierr;
519c14b057cSPeter Brune   DM                      dm;
5209b94acceSBarry Smith 
5213a40ed3dSBarry Smith   PetscFunctionBegin;
5220700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
523ca161407SBarry Smith 
524186905e3SBarry Smith   if (!SNESRegisterAllCalled) {ierr = SNESRegisterAll(PETSC_NULL);CHKERRQ(ierr);}
5253194b578SJed Brown   ierr = PetscObjectOptionsBegin((PetscObject)snes);CHKERRQ(ierr);
5267adad957SLisandro Dalcin     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
527b0a32e0cSBarry Smith     ierr = PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);CHKERRQ(ierr);
528d64ed03dSBarry Smith     if (flg) {
529186905e3SBarry Smith       ierr = SNESSetType(snes,type);CHKERRQ(ierr);
5307adad957SLisandro Dalcin     } else if (!((PetscObject)snes)->type_name) {
531186905e3SBarry Smith       ierr = SNESSetType(snes,deft);CHKERRQ(ierr);
532d64ed03dSBarry Smith     }
53390d69ab7SBarry Smith     /* not used here, but called so will go into help messaage */
534909c8a9fSBarry Smith     ierr = PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);CHKERRQ(ierr);
53593c39befSBarry Smith 
536c60f73f4SPeter Brune     ierr = PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,0);CHKERRQ(ierr);
53757034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);CHKERRQ(ierr);
538186905e3SBarry Smith 
53957034d6fSHong Zhang     ierr = PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);CHKERRQ(ierr);
540b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);CHKERRQ(ierr);
541b0a32e0cSBarry Smith     ierr = PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);CHKERRQ(ierr);
54224254dc1SJed Brown     ierr = PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,PETSC_NULL);CHKERRQ(ierr);
543ddf469c8SBarry Smith     ierr = PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);CHKERRQ(ierr);
544acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);CHKERRQ(ierr);
54585385478SLisandro Dalcin 
546a8054027SBarry Smith     ierr = PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);CHKERRQ(ierr);
547a8054027SBarry Smith     if (flg) {
548a8054027SBarry Smith       ierr = SNESSetLagPreconditioner(snes,lag);CHKERRQ(ierr);
549a8054027SBarry Smith     }
550e35cf81dSBarry Smith     ierr = PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);CHKERRQ(ierr);
551e35cf81dSBarry Smith     if (flg) {
552e35cf81dSBarry Smith       ierr = SNESSetLagJacobian(snes,lag);CHKERRQ(ierr);
553e35cf81dSBarry Smith     }
554efd51863SBarry Smith     ierr = PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);CHKERRQ(ierr);
555efd51863SBarry Smith     if (flg) {
556efd51863SBarry Smith       ierr = SNESSetGridSequence(snes,grids);CHKERRQ(ierr);
557efd51863SBarry Smith     }
558a8054027SBarry Smith 
55985385478SLisandro Dalcin     ierr = PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);CHKERRQ(ierr);
56085385478SLisandro Dalcin     if (flg) {
56185385478SLisandro Dalcin       switch (indx) {
5627f7931b9SBarry Smith       case 0: ierr = SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr); break;
5637f7931b9SBarry Smith       case 1: ierr = SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);    break;
56485385478SLisandro Dalcin       }
56585385478SLisandro Dalcin     }
56685385478SLisandro Dalcin 
567acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);CHKERRQ(ierr);
568186905e3SBarry Smith 
569fdacfa88SPeter Brune     ierr = PetscOptionsEList("-snes_norm_type","SNES Norm type","SNESSetNormType",SNESNormTypes,5,"function",&indx,&flg);CHKERRQ(ierr);
570fdacfa88SPeter Brune     if (flg) { ierr = SNESSetNormType(snes,(SNESNormType)indx);CHKERRQ(ierr); }
571fdacfa88SPeter Brune 
57285385478SLisandro Dalcin     kctx = (SNESKSPEW *)snes->kspconvctx;
57385385478SLisandro Dalcin 
574acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);CHKERRQ(ierr);
575186905e3SBarry Smith 
576fa9f3622SBarry Smith     ierr = PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);CHKERRQ(ierr);
577fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);CHKERRQ(ierr);
578fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);CHKERRQ(ierr);
579fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);CHKERRQ(ierr);
580fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);CHKERRQ(ierr);
581fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);CHKERRQ(ierr);
582fa9f3622SBarry Smith     ierr = PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);CHKERRQ(ierr);
583186905e3SBarry Smith 
58490d69ab7SBarry Smith     flg  = PETSC_FALSE;
585acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
586a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorCancel(snes);CHKERRQ(ierr);}
587eabae89aSBarry Smith 
588a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
589e8105e01SRichard Katz     if (flg) {
590649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
591649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
592e8105e01SRichard Katz     }
593eabae89aSBarry Smith 
594b271bb04SBarry Smith     ierr = PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
595b271bb04SBarry Smith     if (flg) {
596b271bb04SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorRange,0,0);CHKERRQ(ierr);
597b271bb04SBarry Smith     }
598b271bb04SBarry Smith 
599a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
600eabae89aSBarry Smith     if (flg) {
601649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
602f1bef1bcSMatthew Knepley       ierr = SNESMonitorSetRatio(snes,monviewer);CHKERRQ(ierr);
603e8105e01SRichard Katz     }
604eabae89aSBarry Smith 
605a6570f20SBarry Smith     ierr = PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
606eabae89aSBarry Smith     if (flg) {
607649052a6SBarry Smith       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);CHKERRQ(ierr);
608649052a6SBarry Smith       ierr = SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);CHKERRQ(ierr);
609eabae89aSBarry Smith     }
610eabae89aSBarry Smith 
6115180491cSLisandro Dalcin     ierr = PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
6125180491cSLisandro Dalcin     if (flg) {ierr = PetscPythonMonitorSet((PetscObject)snes,monfilename);CHKERRQ(ierr);}
6135180491cSLisandro Dalcin 
61490d69ab7SBarry Smith     flg  = PETSC_FALSE;
615acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
616a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolution,0,0);CHKERRQ(ierr);}
61790d69ab7SBarry Smith     flg  = PETSC_FALSE;
618acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
619a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);CHKERRQ(ierr);}
62090d69ab7SBarry Smith     flg  = PETSC_FALSE;
621acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
622a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorResidual,0,0);CHKERRQ(ierr);}
62390d69ab7SBarry Smith     flg  = PETSC_FALSE;
624acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
625a6570f20SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
62690d69ab7SBarry Smith     flg  = PETSC_FALSE;
627acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
628b271bb04SBarry Smith     if (flg) {ierr = SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);}
629e24b481bSBarry Smith 
63090d69ab7SBarry Smith     flg  = PETSC_FALSE;
631acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);CHKERRQ(ierr);
6324b27c08aSLois Curfman McInnes     if (flg) {
6336cab3a1bSJed Brown       void *functx;
6346cab3a1bSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
6356cab3a1bSJed Brown       ierr = SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,functx);CHKERRQ(ierr);
636ae15b995SBarry Smith       ierr = PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");CHKERRQ(ierr);
6379b94acceSBarry Smith     }
638639f9d9dSBarry Smith 
639aa3661deSLisandro Dalcin     mf = mf_operator = PETSC_FALSE;
640aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
641acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);CHKERRQ(ierr);
642a8248277SBarry Smith     if (flg && mf_operator) {
643a8248277SBarry Smith       snes->mf_operator = PETSC_TRUE;
644a8248277SBarry Smith       mf = PETSC_TRUE;
645a8248277SBarry Smith     }
646aa3661deSLisandro Dalcin     flg = PETSC_FALSE;
647acfcf0e5SJed Brown     ierr = PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);CHKERRQ(ierr);
648aa3661deSLisandro Dalcin     if (!flg && mf_operator) mf = PETSC_TRUE;
649aa3661deSLisandro Dalcin     mf_version = 1;
650aa3661deSLisandro Dalcin     ierr = PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);CHKERRQ(ierr);
651aa3661deSLisandro Dalcin 
652d28543b3SPeter Brune 
65389b92e6fSPeter Brune     /* GS Options */
65489b92e6fSPeter Brune     ierr = PetscOptionsInt("-snes_gs_sweeps","Number of sweeps of GS to apply","SNESComputeGS",snes->gssweeps,&snes->gssweeps,PETSC_NULL);CHKERRQ(ierr);
65589b92e6fSPeter Brune 
65676b2cf59SMatthew Knepley     for(i = 0; i < numberofsetfromoptions; i++) {
65776b2cf59SMatthew Knepley       ierr = (*othersetfromoptions[i])(snes);CHKERRQ(ierr);
65876b2cf59SMatthew Knepley     }
65976b2cf59SMatthew Knepley 
660e7788613SBarry Smith     if (snes->ops->setfromoptions) {
661e7788613SBarry Smith       ierr = (*snes->ops->setfromoptions)(snes);CHKERRQ(ierr);
662639f9d9dSBarry Smith     }
6635d973c19SBarry Smith 
6645d973c19SBarry Smith     /* process any options handlers added with PetscObjectAddOptionsHandler() */
6655d973c19SBarry Smith     ierr = PetscObjectProcessOptionsHandlers((PetscObject)snes);CHKERRQ(ierr);
666b0a32e0cSBarry Smith   ierr = PetscOptionsEnd();CHKERRQ(ierr);
6674bbc92c1SBarry Smith 
668aa3661deSLisandro Dalcin   if (mf) { ierr = SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version);CHKERRQ(ierr); }
6691cee3971SBarry Smith 
6701cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
671aa3661deSLisandro Dalcin   ierr = KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
672aa3661deSLisandro Dalcin   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);CHKERRQ(ierr);
67385385478SLisandro Dalcin   ierr = KSPSetFromOptions(snes->ksp);CHKERRQ(ierr);
67493993e2dSLois Curfman McInnes 
6759e764e56SPeter Brune   if (!snes->linesearch) {
676f1c6b773SPeter Brune     ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);CHKERRQ(ierr);
6779e764e56SPeter Brune   }
678f1c6b773SPeter Brune   ierr = SNESLineSearchSetFromOptions(snes->linesearch);CHKERRQ(ierr);
6799e764e56SPeter Brune 
68051e86f29SPeter Brune   /* if someone has set the SNES PC type, create it. */
68151e86f29SPeter Brune   ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
68251e86f29SPeter Brune   ierr = PetscOptionsHasName(optionsprefix, "-npc_snes_type", &pcset);CHKERRQ(ierr);
68351e86f29SPeter Brune   if (pcset && (!snes->pc)) {
68451e86f29SPeter Brune     ierr = SNESGetPC(snes, &snes->pc);CHKERRQ(ierr);
68551e86f29SPeter Brune   }
6864a0c5b0cSMatthew G Knepley   if (snes->pc) {
687fde0ff24SPeter Brune     ierr = SNESSetOptionsPrefix(snes->pc, optionsprefix);CHKERRQ(ierr);
688fde0ff24SPeter Brune     ierr = SNESAppendOptionsPrefix(snes->pc, "npc_");CHKERRQ(ierr);
689c14b057cSPeter Brune     ierr = SNESGetDM(snes, &dm);CHKERRQ(ierr);
690c14b057cSPeter Brune     ierr = SNESSetDM(snes->pc, dm);CHKERRQ(ierr);
69188976e71SPeter Brune     /* default to 1 iteration */
69288976e71SPeter Brune     ierr = SNESSetTolerances(snes->pc, snes->pc->abstol, snes->pc->rtol, snes->pc->stol, 1, snes->pc->max_funcs);CHKERRQ(ierr);
693534ebe21SPeter Brune     ierr = SNESSetNormType(snes->pc, SNES_NORM_FINAL_ONLY);CHKERRQ(ierr);
6944a0c5b0cSMatthew G Knepley     ierr = SNESSetFromOptions(snes->pc);CHKERRQ(ierr);
6954a0c5b0cSMatthew G Knepley   }
6963a40ed3dSBarry Smith   PetscFunctionReturn(0);
6979b94acceSBarry Smith }
6989b94acceSBarry Smith 
699d25893d9SBarry Smith #undef __FUNCT__
700d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeApplicationContext"
701d25893d9SBarry Smith /*@
702d25893d9SBarry Smith    SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
703d25893d9SBarry Smith    the nonlinear solvers.
704d25893d9SBarry Smith 
705d25893d9SBarry Smith    Logically Collective on SNES
706d25893d9SBarry Smith 
707d25893d9SBarry Smith    Input Parameters:
708d25893d9SBarry Smith +  snes - the SNES context
709d25893d9SBarry Smith .  compute - function to compute the context
710d25893d9SBarry Smith -  destroy - function to destroy the context
711d25893d9SBarry Smith 
712d25893d9SBarry Smith    Level: intermediate
713d25893d9SBarry Smith 
714d25893d9SBarry Smith .keywords: SNES, nonlinear, set, application, context
715d25893d9SBarry Smith 
716d25893d9SBarry Smith .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
717d25893d9SBarry Smith @*/
718d25893d9SBarry Smith PetscErrorCode  SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
719d25893d9SBarry Smith {
720d25893d9SBarry Smith   PetscFunctionBegin;
721d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
722d25893d9SBarry Smith   snes->ops->usercompute = compute;
723d25893d9SBarry Smith   snes->ops->userdestroy = destroy;
724d25893d9SBarry Smith   PetscFunctionReturn(0);
725d25893d9SBarry Smith }
726a847f771SSatish Balay 
7274a2ae208SSatish Balay #undef __FUNCT__
7284a2ae208SSatish Balay #define __FUNCT__ "SNESSetApplicationContext"
729b07ff414SBarry Smith /*@
7309b94acceSBarry Smith    SNESSetApplicationContext - Sets the optional user-defined context for
7319b94acceSBarry Smith    the nonlinear solvers.
7329b94acceSBarry Smith 
7333f9fe445SBarry Smith    Logically Collective on SNES
734fee21e36SBarry Smith 
735c7afd0dbSLois Curfman McInnes    Input Parameters:
736c7afd0dbSLois Curfman McInnes +  snes - the SNES context
737c7afd0dbSLois Curfman McInnes -  usrP - optional user context
738c7afd0dbSLois Curfman McInnes 
73936851e7fSLois Curfman McInnes    Level: intermediate
74036851e7fSLois Curfman McInnes 
7419b94acceSBarry Smith .keywords: SNES, nonlinear, set, application, context
7429b94acceSBarry Smith 
743*ecaffddaSVictor Eijkhout .seealso: SNESGetApplicationContext()
7449b94acceSBarry Smith @*/
7457087cfbeSBarry Smith PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
7469b94acceSBarry Smith {
7471b2093e4SBarry Smith   PetscErrorCode ierr;
748b07ff414SBarry Smith   KSP            ksp;
7491b2093e4SBarry Smith 
7503a40ed3dSBarry Smith   PetscFunctionBegin;
7510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
752b07ff414SBarry Smith   ierr       = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
753b07ff414SBarry Smith   ierr       = KSPSetApplicationContext(ksp,usrP);CHKERRQ(ierr);
7549b94acceSBarry Smith   snes->user = usrP;
7553a40ed3dSBarry Smith   PetscFunctionReturn(0);
7569b94acceSBarry Smith }
75774679c65SBarry Smith 
7584a2ae208SSatish Balay #undef __FUNCT__
7594a2ae208SSatish Balay #define __FUNCT__ "SNESGetApplicationContext"
760b07ff414SBarry Smith /*@
7619b94acceSBarry Smith    SNESGetApplicationContext - Gets the user-defined context for the
7629b94acceSBarry Smith    nonlinear solvers.
7639b94acceSBarry Smith 
764c7afd0dbSLois Curfman McInnes    Not Collective
765c7afd0dbSLois Curfman McInnes 
7669b94acceSBarry Smith    Input Parameter:
7679b94acceSBarry Smith .  snes - SNES context
7689b94acceSBarry Smith 
7699b94acceSBarry Smith    Output Parameter:
7709b94acceSBarry Smith .  usrP - user context
7719b94acceSBarry Smith 
77236851e7fSLois Curfman McInnes    Level: intermediate
77336851e7fSLois Curfman McInnes 
7749b94acceSBarry Smith .keywords: SNES, nonlinear, get, application, context
7759b94acceSBarry Smith 
7769b94acceSBarry Smith .seealso: SNESSetApplicationContext()
7779b94acceSBarry Smith @*/
778e71120c6SJed Brown PetscErrorCode  SNESGetApplicationContext(SNES snes,void *usrP)
7799b94acceSBarry Smith {
7803a40ed3dSBarry Smith   PetscFunctionBegin;
7810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
782e71120c6SJed Brown   *(void**)usrP = snes->user;
7833a40ed3dSBarry Smith   PetscFunctionReturn(0);
7849b94acceSBarry Smith }
78574679c65SBarry Smith 
7864a2ae208SSatish Balay #undef __FUNCT__
7874a2ae208SSatish Balay #define __FUNCT__ "SNESGetIterationNumber"
7889b94acceSBarry Smith /*@
789c8228a4eSBarry Smith    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
790c8228a4eSBarry Smith    at this time.
7919b94acceSBarry Smith 
792c7afd0dbSLois Curfman McInnes    Not Collective
793c7afd0dbSLois Curfman McInnes 
7949b94acceSBarry Smith    Input Parameter:
7959b94acceSBarry Smith .  snes - SNES context
7969b94acceSBarry Smith 
7979b94acceSBarry Smith    Output Parameter:
7989b94acceSBarry Smith .  iter - iteration number
7999b94acceSBarry Smith 
800c8228a4eSBarry Smith    Notes:
801c8228a4eSBarry Smith    For example, during the computation of iteration 2 this would return 1.
802c8228a4eSBarry Smith 
803c8228a4eSBarry Smith    This is useful for using lagged Jacobians (where one does not recompute the
80408405cd6SLois Curfman McInnes    Jacobian at each SNES iteration). For example, the code
80508405cd6SLois Curfman McInnes .vb
80608405cd6SLois Curfman McInnes       ierr = SNESGetIterationNumber(snes,&it);
80708405cd6SLois Curfman McInnes       if (!(it % 2)) {
80808405cd6SLois Curfman McInnes         [compute Jacobian here]
80908405cd6SLois Curfman McInnes       }
81008405cd6SLois Curfman McInnes .ve
811c8228a4eSBarry Smith    can be used in your ComputeJacobian() function to cause the Jacobian to be
81208405cd6SLois Curfman McInnes    recomputed every second SNES iteration.
813c8228a4eSBarry Smith 
81436851e7fSLois Curfman McInnes    Level: intermediate
81536851e7fSLois Curfman McInnes 
8162b668275SBarry Smith .keywords: SNES, nonlinear, get, iteration, number,
8172b668275SBarry Smith 
818b850b91aSLisandro Dalcin .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
8199b94acceSBarry Smith @*/
8207087cfbeSBarry Smith PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
8219b94acceSBarry Smith {
8223a40ed3dSBarry Smith   PetscFunctionBegin;
8230700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8244482741eSBarry Smith   PetscValidIntPointer(iter,2);
8259b94acceSBarry Smith   *iter = snes->iter;
8263a40ed3dSBarry Smith   PetscFunctionReturn(0);
8279b94acceSBarry Smith }
82874679c65SBarry Smith 
8294a2ae208SSatish Balay #undef __FUNCT__
830360c497dSPeter Brune #define __FUNCT__ "SNESSetIterationNumber"
831360c497dSPeter Brune /*@
832360c497dSPeter Brune    SNESSetIterationNumber - Sets the current iteration number.
833360c497dSPeter Brune 
834360c497dSPeter Brune    Not Collective
835360c497dSPeter Brune 
836360c497dSPeter Brune    Input Parameter:
837360c497dSPeter Brune .  snes - SNES context
838360c497dSPeter Brune .  iter - iteration number
839360c497dSPeter Brune 
840360c497dSPeter Brune    Level: developer
841360c497dSPeter Brune 
842360c497dSPeter Brune .keywords: SNES, nonlinear, set, iteration, number,
843360c497dSPeter Brune 
844360c497dSPeter Brune .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
845360c497dSPeter Brune @*/
846360c497dSPeter Brune PetscErrorCode  SNESSetIterationNumber(SNES snes,PetscInt iter)
847360c497dSPeter Brune {
848360c497dSPeter Brune   PetscErrorCode ierr;
849360c497dSPeter Brune 
850360c497dSPeter Brune   PetscFunctionBegin;
851360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
852360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
853360c497dSPeter Brune   snes->iter = iter;
854360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
855360c497dSPeter Brune   PetscFunctionReturn(0);
856360c497dSPeter Brune }
857360c497dSPeter Brune 
858360c497dSPeter Brune #undef __FUNCT__
8594a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunctionNorm"
8609b94acceSBarry Smith /*@
8619b94acceSBarry Smith    SNESGetFunctionNorm - Gets the norm of the current function that was set
8629b94acceSBarry Smith    with SNESSSetFunction().
8639b94acceSBarry Smith 
864c7afd0dbSLois Curfman McInnes    Collective on SNES
865c7afd0dbSLois Curfman McInnes 
8669b94acceSBarry Smith    Input Parameter:
8679b94acceSBarry Smith .  snes - SNES context
8689b94acceSBarry Smith 
8699b94acceSBarry Smith    Output Parameter:
8709b94acceSBarry Smith .  fnorm - 2-norm of function
8719b94acceSBarry Smith 
87236851e7fSLois Curfman McInnes    Level: intermediate
87336851e7fSLois Curfman McInnes 
8749b94acceSBarry Smith .keywords: SNES, nonlinear, get, function, norm
875a86d99e1SLois Curfman McInnes 
876b850b91aSLisandro Dalcin .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
8779b94acceSBarry Smith @*/
8787087cfbeSBarry Smith PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
8799b94acceSBarry Smith {
8803a40ed3dSBarry Smith   PetscFunctionBegin;
8810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
8824482741eSBarry Smith   PetscValidScalarPointer(fnorm,2);
8839b94acceSBarry Smith   *fnorm = snes->norm;
8843a40ed3dSBarry Smith   PetscFunctionReturn(0);
8859b94acceSBarry Smith }
88674679c65SBarry Smith 
887360c497dSPeter Brune 
888360c497dSPeter Brune #undef __FUNCT__
889360c497dSPeter Brune #define __FUNCT__ "SNESSetFunctionNorm"
890360c497dSPeter Brune /*@
891360c497dSPeter Brune    SNESSetFunctionNorm - Sets the 2-norm of the current function computed using VecNorm().
892360c497dSPeter Brune 
893360c497dSPeter Brune    Collective on SNES
894360c497dSPeter Brune 
895360c497dSPeter Brune    Input Parameter:
896360c497dSPeter Brune .  snes - SNES context
897360c497dSPeter Brune .  fnorm - 2-norm of function
898360c497dSPeter Brune 
899360c497dSPeter Brune    Level: developer
900360c497dSPeter Brune 
901360c497dSPeter Brune .keywords: SNES, nonlinear, set, function, norm
902360c497dSPeter Brune 
903360c497dSPeter Brune .seealso: SNESSetFunction(), SNESSetIterationNumber(), VecNorm().
904360c497dSPeter Brune @*/
905360c497dSPeter Brune PetscErrorCode  SNESSetFunctionNorm(SNES snes,PetscReal fnorm)
906360c497dSPeter Brune {
907360c497dSPeter Brune 
908360c497dSPeter Brune   PetscErrorCode ierr;
909360c497dSPeter Brune 
910360c497dSPeter Brune   PetscFunctionBegin;
911360c497dSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
912360c497dSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
913360c497dSPeter Brune   snes->norm = fnorm;
914360c497dSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
915360c497dSPeter Brune   PetscFunctionReturn(0);
916360c497dSPeter Brune }
917360c497dSPeter Brune 
9184a2ae208SSatish Balay #undef __FUNCT__
919b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetNonlinearStepFailures"
9209b94acceSBarry Smith /*@
921b850b91aSLisandro Dalcin    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
9229b94acceSBarry Smith    attempted by the nonlinear solver.
9239b94acceSBarry Smith 
924c7afd0dbSLois Curfman McInnes    Not Collective
925c7afd0dbSLois Curfman McInnes 
9269b94acceSBarry Smith    Input Parameter:
9279b94acceSBarry Smith .  snes - SNES context
9289b94acceSBarry Smith 
9299b94acceSBarry Smith    Output Parameter:
9309b94acceSBarry Smith .  nfails - number of unsuccessful steps attempted
9319b94acceSBarry Smith 
932c96a6f78SLois Curfman McInnes    Notes:
933c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
934c96a6f78SLois Curfman McInnes 
93536851e7fSLois Curfman McInnes    Level: intermediate
93636851e7fSLois Curfman McInnes 
9379b94acceSBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
93858ebbce7SBarry Smith 
939e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
94058ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
9419b94acceSBarry Smith @*/
9427087cfbeSBarry Smith PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
9439b94acceSBarry Smith {
9443a40ed3dSBarry Smith   PetscFunctionBegin;
9450700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
9464482741eSBarry Smith   PetscValidIntPointer(nfails,2);
94750ffb88aSMatthew Knepley   *nfails = snes->numFailures;
94850ffb88aSMatthew Knepley   PetscFunctionReturn(0);
94950ffb88aSMatthew Knepley }
95050ffb88aSMatthew Knepley 
95150ffb88aSMatthew Knepley #undef __FUNCT__
952b850b91aSLisandro Dalcin #define __FUNCT__ "SNESSetMaxNonlinearStepFailures"
95350ffb88aSMatthew Knepley /*@
954b850b91aSLisandro Dalcin    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
95550ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
95650ffb88aSMatthew Knepley 
95750ffb88aSMatthew Knepley    Not Collective
95850ffb88aSMatthew Knepley 
95950ffb88aSMatthew Knepley    Input Parameters:
96050ffb88aSMatthew Knepley +  snes     - SNES context
96150ffb88aSMatthew Knepley -  maxFails - maximum of unsuccessful steps
96250ffb88aSMatthew Knepley 
96350ffb88aSMatthew Knepley    Level: intermediate
96450ffb88aSMatthew Knepley 
96550ffb88aSMatthew Knepley .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
96658ebbce7SBarry Smith 
967e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
96858ebbce7SBarry Smith           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
96950ffb88aSMatthew Knepley @*/
9707087cfbeSBarry Smith PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
97150ffb88aSMatthew Knepley {
97250ffb88aSMatthew Knepley   PetscFunctionBegin;
9730700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
97450ffb88aSMatthew Knepley   snes->maxFailures = maxFails;
97550ffb88aSMatthew Knepley   PetscFunctionReturn(0);
97650ffb88aSMatthew Knepley }
97750ffb88aSMatthew Knepley 
97850ffb88aSMatthew Knepley #undef __FUNCT__
979b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetMaxNonlinearStepFailures"
98050ffb88aSMatthew Knepley /*@
981b850b91aSLisandro Dalcin    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
98250ffb88aSMatthew Knepley    attempted by the nonlinear solver before it gives up.
98350ffb88aSMatthew Knepley 
98450ffb88aSMatthew Knepley    Not Collective
98550ffb88aSMatthew Knepley 
98650ffb88aSMatthew Knepley    Input Parameter:
98750ffb88aSMatthew Knepley .  snes     - SNES context
98850ffb88aSMatthew Knepley 
98950ffb88aSMatthew Knepley    Output Parameter:
99050ffb88aSMatthew Knepley .  maxFails - maximum of unsuccessful steps
99150ffb88aSMatthew Knepley 
99250ffb88aSMatthew Knepley    Level: intermediate
99350ffb88aSMatthew Knepley 
99450ffb88aSMatthew Knepley .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
99558ebbce7SBarry Smith 
996e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
99758ebbce7SBarry Smith           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
99858ebbce7SBarry Smith 
99950ffb88aSMatthew Knepley @*/
10007087cfbeSBarry Smith PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
100150ffb88aSMatthew Knepley {
100250ffb88aSMatthew Knepley   PetscFunctionBegin;
10030700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10044482741eSBarry Smith   PetscValidIntPointer(maxFails,2);
100550ffb88aSMatthew Knepley   *maxFails = snes->maxFailures;
10063a40ed3dSBarry Smith   PetscFunctionReturn(0);
10079b94acceSBarry Smith }
1008a847f771SSatish Balay 
10094a2ae208SSatish Balay #undef __FUNCT__
10102541af92SBarry Smith #define __FUNCT__ "SNESGetNumberFunctionEvals"
10112541af92SBarry Smith /*@
10122541af92SBarry Smith    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
10132541af92SBarry Smith      done by SNES.
10142541af92SBarry Smith 
10152541af92SBarry Smith    Not Collective
10162541af92SBarry Smith 
10172541af92SBarry Smith    Input Parameter:
10182541af92SBarry Smith .  snes     - SNES context
10192541af92SBarry Smith 
10202541af92SBarry Smith    Output Parameter:
10212541af92SBarry Smith .  nfuncs - number of evaluations
10222541af92SBarry Smith 
10232541af92SBarry Smith    Level: intermediate
10242541af92SBarry Smith 
10252541af92SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
102658ebbce7SBarry Smith 
1027e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
10282541af92SBarry Smith @*/
10297087cfbeSBarry Smith PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
10302541af92SBarry Smith {
10312541af92SBarry Smith   PetscFunctionBegin;
10320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10332541af92SBarry Smith   PetscValidIntPointer(nfuncs,2);
10342541af92SBarry Smith   *nfuncs = snes->nfuncs;
10352541af92SBarry Smith   PetscFunctionReturn(0);
10362541af92SBarry Smith }
10372541af92SBarry Smith 
10382541af92SBarry Smith #undef __FUNCT__
10393d4c4710SBarry Smith #define __FUNCT__ "SNESGetLinearSolveFailures"
10403d4c4710SBarry Smith /*@
10413d4c4710SBarry Smith    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
10423d4c4710SBarry Smith    linear solvers.
10433d4c4710SBarry Smith 
10443d4c4710SBarry Smith    Not Collective
10453d4c4710SBarry Smith 
10463d4c4710SBarry Smith    Input Parameter:
10473d4c4710SBarry Smith .  snes - SNES context
10483d4c4710SBarry Smith 
10493d4c4710SBarry Smith    Output Parameter:
10503d4c4710SBarry Smith .  nfails - number of failed solves
10513d4c4710SBarry Smith 
10523d4c4710SBarry Smith    Notes:
10533d4c4710SBarry Smith    This counter is reset to zero for each successive call to SNESSolve().
10543d4c4710SBarry Smith 
10553d4c4710SBarry Smith    Level: intermediate
10563d4c4710SBarry Smith 
10573d4c4710SBarry Smith .keywords: SNES, nonlinear, get, number, unsuccessful, steps
105858ebbce7SBarry Smith 
1059e1c61ce8SBarry Smith .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
10603d4c4710SBarry Smith @*/
10617087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
10623d4c4710SBarry Smith {
10633d4c4710SBarry Smith   PetscFunctionBegin;
10640700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
10653d4c4710SBarry Smith   PetscValidIntPointer(nfails,2);
10663d4c4710SBarry Smith   *nfails = snes->numLinearSolveFailures;
10673d4c4710SBarry Smith   PetscFunctionReturn(0);
10683d4c4710SBarry Smith }
10693d4c4710SBarry Smith 
10703d4c4710SBarry Smith #undef __FUNCT__
10713d4c4710SBarry Smith #define __FUNCT__ "SNESSetMaxLinearSolveFailures"
10723d4c4710SBarry Smith /*@
10733d4c4710SBarry Smith    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
10743d4c4710SBarry Smith    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
10753d4c4710SBarry Smith 
10763f9fe445SBarry Smith    Logically Collective on SNES
10773d4c4710SBarry Smith 
10783d4c4710SBarry Smith    Input Parameters:
10793d4c4710SBarry Smith +  snes     - SNES context
10803d4c4710SBarry Smith -  maxFails - maximum allowed linear solve failures
10813d4c4710SBarry Smith 
10823d4c4710SBarry Smith    Level: intermediate
10833d4c4710SBarry Smith 
1084a6796414SBarry Smith    Notes: By default this is 0; that is SNES returns on the first failed linear solve
10853d4c4710SBarry Smith 
10863d4c4710SBarry Smith .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
10873d4c4710SBarry Smith 
108858ebbce7SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
10893d4c4710SBarry Smith @*/
10907087cfbeSBarry Smith PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
10913d4c4710SBarry Smith {
10923d4c4710SBarry Smith   PetscFunctionBegin;
10930700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1094c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxFails,2);
10953d4c4710SBarry Smith   snes->maxLinearSolveFailures = maxFails;
10963d4c4710SBarry Smith   PetscFunctionReturn(0);
10973d4c4710SBarry Smith }
10983d4c4710SBarry Smith 
10993d4c4710SBarry Smith #undef __FUNCT__
11003d4c4710SBarry Smith #define __FUNCT__ "SNESGetMaxLinearSolveFailures"
11013d4c4710SBarry Smith /*@
11023d4c4710SBarry Smith    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
11033d4c4710SBarry Smith      are allowed before SNES terminates
11043d4c4710SBarry Smith 
11053d4c4710SBarry Smith    Not Collective
11063d4c4710SBarry Smith 
11073d4c4710SBarry Smith    Input Parameter:
11083d4c4710SBarry Smith .  snes     - SNES context
11093d4c4710SBarry Smith 
11103d4c4710SBarry Smith    Output Parameter:
11113d4c4710SBarry Smith .  maxFails - maximum of unsuccessful solves allowed
11123d4c4710SBarry Smith 
11133d4c4710SBarry Smith    Level: intermediate
11143d4c4710SBarry Smith 
11153d4c4710SBarry Smith    Notes: By default this is 1; that is SNES returns on the first failed linear solve
11163d4c4710SBarry Smith 
11173d4c4710SBarry Smith .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
11183d4c4710SBarry Smith 
1119e1c61ce8SBarry Smith .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
11203d4c4710SBarry Smith @*/
11217087cfbeSBarry Smith PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
11223d4c4710SBarry Smith {
11233d4c4710SBarry Smith   PetscFunctionBegin;
11240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11253d4c4710SBarry Smith   PetscValidIntPointer(maxFails,2);
11263d4c4710SBarry Smith   *maxFails = snes->maxLinearSolveFailures;
11273d4c4710SBarry Smith   PetscFunctionReturn(0);
11283d4c4710SBarry Smith }
11293d4c4710SBarry Smith 
11303d4c4710SBarry Smith #undef __FUNCT__
1131b850b91aSLisandro Dalcin #define __FUNCT__ "SNESGetLinearSolveIterations"
1132c96a6f78SLois Curfman McInnes /*@
1133b850b91aSLisandro Dalcin    SNESGetLinearSolveIterations - Gets the total number of linear iterations
1134c96a6f78SLois Curfman McInnes    used by the nonlinear solver.
1135c96a6f78SLois Curfman McInnes 
1136c7afd0dbSLois Curfman McInnes    Not Collective
1137c7afd0dbSLois Curfman McInnes 
1138c96a6f78SLois Curfman McInnes    Input Parameter:
1139c96a6f78SLois Curfman McInnes .  snes - SNES context
1140c96a6f78SLois Curfman McInnes 
1141c96a6f78SLois Curfman McInnes    Output Parameter:
1142c96a6f78SLois Curfman McInnes .  lits - number of linear iterations
1143c96a6f78SLois Curfman McInnes 
1144c96a6f78SLois Curfman McInnes    Notes:
1145c96a6f78SLois Curfman McInnes    This counter is reset to zero for each successive call to SNESSolve().
1146c96a6f78SLois Curfman McInnes 
114736851e7fSLois Curfman McInnes    Level: intermediate
114836851e7fSLois Curfman McInnes 
1149c96a6f78SLois Curfman McInnes .keywords: SNES, nonlinear, get, number, linear, iterations
11502b668275SBarry Smith 
11518c7482ecSBarry Smith .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
1152c96a6f78SLois Curfman McInnes @*/
11537087cfbeSBarry Smith PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
1154c96a6f78SLois Curfman McInnes {
11553a40ed3dSBarry Smith   PetscFunctionBegin;
11560700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11574482741eSBarry Smith   PetscValidIntPointer(lits,2);
1158c96a6f78SLois Curfman McInnes   *lits = snes->linear_its;
11593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1160c96a6f78SLois Curfman McInnes }
1161c96a6f78SLois Curfman McInnes 
11624a2ae208SSatish Balay #undef __FUNCT__
116394b7f48cSBarry Smith #define __FUNCT__ "SNESGetKSP"
116452baeb72SSatish Balay /*@
116594b7f48cSBarry Smith    SNESGetKSP - Returns the KSP context for a SNES solver.
11669b94acceSBarry Smith 
116794b7f48cSBarry Smith    Not Collective, but if SNES object is parallel, then KSP object is parallel
1168c7afd0dbSLois Curfman McInnes 
11699b94acceSBarry Smith    Input Parameter:
11709b94acceSBarry Smith .  snes - the SNES context
11719b94acceSBarry Smith 
11729b94acceSBarry Smith    Output Parameter:
117394b7f48cSBarry Smith .  ksp - the KSP context
11749b94acceSBarry Smith 
11759b94acceSBarry Smith    Notes:
117694b7f48cSBarry Smith    The user can then directly manipulate the KSP context to set various
11779b94acceSBarry Smith    options, etc.  Likewise, the user can then extract and manipulate the
11782999313aSBarry Smith    PC contexts as well.
11799b94acceSBarry Smith 
118036851e7fSLois Curfman McInnes    Level: beginner
118136851e7fSLois Curfman McInnes 
118294b7f48cSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
11839b94acceSBarry Smith 
11842999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
11859b94acceSBarry Smith @*/
11867087cfbeSBarry Smith PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
11879b94acceSBarry Smith {
11881cee3971SBarry Smith   PetscErrorCode ierr;
11891cee3971SBarry Smith 
11903a40ed3dSBarry Smith   PetscFunctionBegin;
11910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
11924482741eSBarry Smith   PetscValidPointer(ksp,2);
11931cee3971SBarry Smith 
11941cee3971SBarry Smith   if (!snes->ksp) {
11951cee3971SBarry Smith     ierr = KSPCreate(((PetscObject)snes)->comm,&snes->ksp);CHKERRQ(ierr);
11961cee3971SBarry Smith     ierr = PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);CHKERRQ(ierr);
11971cee3971SBarry Smith     ierr = PetscLogObjectParent(snes,snes->ksp);CHKERRQ(ierr);
11981cee3971SBarry Smith   }
119994b7f48cSBarry Smith   *ksp = snes->ksp;
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
12019b94acceSBarry Smith }
120282bf6240SBarry Smith 
12034a2ae208SSatish Balay #undef __FUNCT__
12042999313aSBarry Smith #define __FUNCT__ "SNESSetKSP"
12052999313aSBarry Smith /*@
12062999313aSBarry Smith    SNESSetKSP - Sets a KSP context for the SNES object to use
12072999313aSBarry Smith 
12082999313aSBarry Smith    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
12092999313aSBarry Smith 
12102999313aSBarry Smith    Input Parameters:
12112999313aSBarry Smith +  snes - the SNES context
12122999313aSBarry Smith -  ksp - the KSP context
12132999313aSBarry Smith 
12142999313aSBarry Smith    Notes:
12152999313aSBarry Smith    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
12162999313aSBarry Smith    so this routine is rarely needed.
12172999313aSBarry Smith 
12182999313aSBarry Smith    The KSP object that is already in the SNES object has its reference count
12192999313aSBarry Smith    decreased by one.
12202999313aSBarry Smith 
12212999313aSBarry Smith    Level: developer
12222999313aSBarry Smith 
12232999313aSBarry Smith .keywords: SNES, nonlinear, get, KSP, context
12242999313aSBarry Smith 
12252999313aSBarry Smith .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
12262999313aSBarry Smith @*/
12277087cfbeSBarry Smith PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
12282999313aSBarry Smith {
12292999313aSBarry Smith   PetscErrorCode ierr;
12302999313aSBarry Smith 
12312999313aSBarry Smith   PetscFunctionBegin;
12320700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
12330700a824SBarry Smith   PetscValidHeaderSpecific(ksp,KSP_CLASSID,2);
12342999313aSBarry Smith   PetscCheckSameComm(snes,1,ksp,2);
12357dcf0eaaSdalcinl   ierr = PetscObjectReference((PetscObject)ksp);CHKERRQ(ierr);
1236906ed7ccSBarry Smith   if (snes->ksp) {ierr = PetscObjectDereference((PetscObject)snes->ksp);CHKERRQ(ierr);}
12372999313aSBarry Smith   snes->ksp = ksp;
12382999313aSBarry Smith   PetscFunctionReturn(0);
12392999313aSBarry Smith }
12402999313aSBarry Smith 
12417adad957SLisandro Dalcin #if 0
12422999313aSBarry Smith #undef __FUNCT__
12434a2ae208SSatish Balay #define __FUNCT__ "SNESPublish_Petsc"
12446849ba73SBarry Smith static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1245e24b481bSBarry Smith {
1246e24b481bSBarry Smith   PetscFunctionBegin;
1247e24b481bSBarry Smith   PetscFunctionReturn(0);
1248e24b481bSBarry Smith }
12497adad957SLisandro Dalcin #endif
1250e24b481bSBarry Smith 
12519b94acceSBarry Smith /* -----------------------------------------------------------*/
12524a2ae208SSatish Balay #undef __FUNCT__
12534a2ae208SSatish Balay #define __FUNCT__ "SNESCreate"
125452baeb72SSatish Balay /*@
12559b94acceSBarry Smith    SNESCreate - Creates a nonlinear solver context.
12569b94acceSBarry Smith 
1257c7afd0dbSLois Curfman McInnes    Collective on MPI_Comm
1258c7afd0dbSLois Curfman McInnes 
1259c7afd0dbSLois Curfman McInnes    Input Parameters:
1260906ed7ccSBarry Smith .  comm - MPI communicator
12619b94acceSBarry Smith 
12629b94acceSBarry Smith    Output Parameter:
12639b94acceSBarry Smith .  outsnes - the new SNES context
12649b94acceSBarry Smith 
1265c7afd0dbSLois Curfman McInnes    Options Database Keys:
1266c7afd0dbSLois Curfman McInnes +   -snes_mf - Activates default matrix-free Jacobian-vector products,
1267c7afd0dbSLois Curfman McInnes                and no preconditioning matrix
1268c7afd0dbSLois Curfman McInnes .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
1269c7afd0dbSLois Curfman McInnes                products, and a user-provided preconditioning matrix
1270c7afd0dbSLois Curfman McInnes                as set by SNESSetJacobian()
1271c7afd0dbSLois Curfman McInnes -   -snes_fd - Uses (slow!) finite differences to compute Jacobian
1272c1f60f51SBarry Smith 
127336851e7fSLois Curfman McInnes    Level: beginner
127436851e7fSLois Curfman McInnes 
12759b94acceSBarry Smith .keywords: SNES, nonlinear, create, context
12769b94acceSBarry Smith 
1277a8054027SBarry Smith .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1278a8054027SBarry Smith 
12799b94acceSBarry Smith @*/
12807087cfbeSBarry Smith PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
12819b94acceSBarry Smith {
1282dfbe8321SBarry Smith   PetscErrorCode      ierr;
12839b94acceSBarry Smith   SNES                snes;
1284fa9f3622SBarry Smith   SNESKSPEW           *kctx;
128537fcc0dbSBarry Smith 
12863a40ed3dSBarry Smith   PetscFunctionBegin;
1287ed1caa07SMatthew Knepley   PetscValidPointer(outsnes,2);
12888ba1e511SMatthew Knepley   *outsnes = PETSC_NULL;
12898ba1e511SMatthew Knepley #ifndef PETSC_USE_DYNAMIC_LIBRARIES
12908ba1e511SMatthew Knepley   ierr = SNESInitializePackage(PETSC_NULL);CHKERRQ(ierr);
12918ba1e511SMatthew Knepley #endif
12928ba1e511SMatthew Knepley 
12933194b578SJed Brown   ierr = PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);CHKERRQ(ierr);
12947adad957SLisandro Dalcin 
129585385478SLisandro Dalcin   snes->ops->converged    = SNESDefaultConverged;
12962c155ee1SBarry Smith   snes->usesksp           = PETSC_TRUE;
129788976e71SPeter Brune   snes->tolerancesset     = PETSC_FALSE;
12989b94acceSBarry Smith   snes->max_its           = 50;
12999750a799SBarry Smith   snes->max_funcs         = 10000;
13009b94acceSBarry Smith   snes->norm              = 0.0;
1301fdacfa88SPeter Brune   snes->normtype          = SNES_NORM_FUNCTION;
1302b4874afaSBarry Smith   snes->rtol              = 1.e-8;
1303b4874afaSBarry Smith   snes->ttol              = 0.0;
130470441072SBarry Smith   snes->abstol            = 1.e-50;
1305c60f73f4SPeter Brune   snes->stol              = 1.e-8;
13064b27c08aSLois Curfman McInnes   snes->deltatol          = 1.e-12;
13079b94acceSBarry Smith   snes->nfuncs            = 0;
130850ffb88aSMatthew Knepley   snes->numFailures       = 0;
130950ffb88aSMatthew Knepley   snes->maxFailures       = 1;
13107a00f4a9SLois Curfman McInnes   snes->linear_its        = 0;
1311e35cf81dSBarry Smith   snes->lagjacobian       = 1;
1312a8054027SBarry Smith   snes->lagpreconditioner = 1;
1313639f9d9dSBarry Smith   snes->numbermonitors    = 0;
13149b94acceSBarry Smith   snes->data              = 0;
13154dc4c822SBarry Smith   snes->setupcalled       = PETSC_FALSE;
1316186905e3SBarry Smith   snes->ksp_ewconv        = PETSC_FALSE;
13176f24a144SLois Curfman McInnes   snes->nwork             = 0;
131858c9b817SLisandro Dalcin   snes->work              = 0;
131958c9b817SLisandro Dalcin   snes->nvwork            = 0;
132058c9b817SLisandro Dalcin   snes->vwork             = 0;
1321758f92a0SBarry Smith   snes->conv_hist_len     = 0;
1322758f92a0SBarry Smith   snes->conv_hist_max     = 0;
1323758f92a0SBarry Smith   snes->conv_hist         = PETSC_NULL;
1324758f92a0SBarry Smith   snes->conv_hist_its     = PETSC_NULL;
1325758f92a0SBarry Smith   snes->conv_hist_reset   = PETSC_TRUE;
1326e4ed7901SPeter Brune   snes->vec_func_init_set = PETSC_FALSE;
1327e4ed7901SPeter Brune   snes->norm_init         = 0.;
1328e4ed7901SPeter Brune   snes->norm_init_set     = PETSC_FALSE;
1329184914b5SBarry Smith   snes->reason            = SNES_CONVERGED_ITERATING;
133089b92e6fSPeter Brune   snes->gssweeps          = 1;
13319b94acceSBarry Smith 
13323d4c4710SBarry Smith   snes->numLinearSolveFailures = 0;
13333d4c4710SBarry Smith   snes->maxLinearSolveFailures = 1;
13343d4c4710SBarry Smith 
13359b94acceSBarry Smith   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
133638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(snes,SNESKSPEW,&kctx);CHKERRQ(ierr);
13379b94acceSBarry Smith   snes->kspconvctx  = (void*)kctx;
13389b94acceSBarry Smith   kctx->version     = 2;
13399b94acceSBarry Smith   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
13409b94acceSBarry Smith                              this was too large for some test cases */
134175567043SBarry Smith   kctx->rtol_last   = 0.0;
13429b94acceSBarry Smith   kctx->rtol_max    = .9;
13439b94acceSBarry Smith   kctx->gamma       = 1.0;
134462d1f40fSBarry Smith   kctx->alpha       = .5*(1.0 + PetscSqrtReal(5.0));
134571f87433Sdalcinl   kctx->alpha2      = kctx->alpha;
13469b94acceSBarry Smith   kctx->threshold   = .1;
134775567043SBarry Smith   kctx->lresid_last = 0.0;
134875567043SBarry Smith   kctx->norm_last   = 0.0;
13499b94acceSBarry Smith 
13509b94acceSBarry Smith   *outsnes = snes;
13513a40ed3dSBarry Smith   PetscFunctionReturn(0);
13529b94acceSBarry Smith }
13539b94acceSBarry Smith 
13544a2ae208SSatish Balay #undef __FUNCT__
13554a2ae208SSatish Balay #define __FUNCT__ "SNESSetFunction"
13569b94acceSBarry Smith /*@C
13579b94acceSBarry Smith    SNESSetFunction - Sets the function evaluation routine and function
13589b94acceSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
13599b94acceSBarry Smith    equations.
13609b94acceSBarry Smith 
13613f9fe445SBarry Smith    Logically Collective on SNES
1362fee21e36SBarry Smith 
1363c7afd0dbSLois Curfman McInnes    Input Parameters:
1364c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1365c7afd0dbSLois Curfman McInnes .  r - vector to store function value
1366de044059SHong Zhang .  func - function evaluation routine
1367c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
1368c7afd0dbSLois Curfman McInnes          function evaluation routine (may be PETSC_NULL)
13699b94acceSBarry Smith 
1370c7afd0dbSLois Curfman McInnes    Calling sequence of func:
13718d76a1e5SLois Curfman McInnes $    func (SNES snes,Vec x,Vec f,void *ctx);
1372c7afd0dbSLois Curfman McInnes 
1373c586c404SJed Brown +  snes - the SNES context
1374c586c404SJed Brown .  x - state at which to evaluate residual
1375c586c404SJed Brown .  f - vector to put residual
1376c7afd0dbSLois Curfman McInnes -  ctx - optional user-defined function context
13779b94acceSBarry Smith 
13789b94acceSBarry Smith    Notes:
13799b94acceSBarry Smith    The Newton-like methods typically solve linear systems of the form
13809b94acceSBarry Smith $      f'(x) x = -f(x),
1381c7afd0dbSLois Curfman McInnes    where f'(x) denotes the Jacobian matrix and f(x) is the function.
13829b94acceSBarry Smith 
138336851e7fSLois Curfman McInnes    Level: beginner
138436851e7fSLois Curfman McInnes 
13859b94acceSBarry Smith .keywords: SNES, nonlinear, set, function
13869b94acceSBarry Smith 
13878b0a5094SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetPicard()
13889b94acceSBarry Smith @*/
13897087cfbeSBarry Smith PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
13909b94acceSBarry Smith {
139185385478SLisandro Dalcin   PetscErrorCode ierr;
13926cab3a1bSJed Brown   DM             dm;
13936cab3a1bSJed Brown 
13943a40ed3dSBarry Smith   PetscFunctionBegin;
13950700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1396d2a683ecSLisandro Dalcin   if (r) {
1397d2a683ecSLisandro Dalcin     PetscValidHeaderSpecific(r,VEC_CLASSID,2);
1398d2a683ecSLisandro Dalcin     PetscCheckSameComm(snes,1,r,2);
139985385478SLisandro Dalcin     ierr = PetscObjectReference((PetscObject)r);CHKERRQ(ierr);
14006bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
140185385478SLisandro Dalcin     snes->vec_func = r;
1402d2a683ecSLisandro Dalcin   }
14036cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
14046cab3a1bSJed Brown   ierr = DMSNESSetFunction(dm,func,ctx);CHKERRQ(ierr);
14053a40ed3dSBarry Smith   PetscFunctionReturn(0);
14069b94acceSBarry Smith }
14079b94acceSBarry Smith 
1408646217ecSPeter Brune 
1409646217ecSPeter Brune #undef __FUNCT__
1410e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunction"
1411e4ed7901SPeter Brune /*@C
1412e4ed7901SPeter Brune    SNESSetInitialFunction - Sets the function vector to be used as the
1413e4ed7901SPeter Brune    function norm at the initialization of the method.  In some
1414e4ed7901SPeter Brune    instances, the user has precomputed the function before calling
1415e4ed7901SPeter Brune    SNESSolve.  This function allows one to avoid a redundant call
1416e4ed7901SPeter Brune    to SNESComputeFunction in that case.
1417e4ed7901SPeter Brune 
1418e4ed7901SPeter Brune    Logically Collective on SNES
1419e4ed7901SPeter Brune 
1420e4ed7901SPeter Brune    Input Parameters:
1421e4ed7901SPeter Brune +  snes - the SNES context
1422e4ed7901SPeter Brune -  f - vector to store function value
1423e4ed7901SPeter Brune 
1424e4ed7901SPeter Brune    Notes:
1425e4ed7901SPeter Brune    This should not be modified during the solution procedure.
1426e4ed7901SPeter Brune 
1427e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1428e4ed7901SPeter Brune 
1429e4ed7901SPeter Brune    Level: developer
1430e4ed7901SPeter Brune 
1431e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function
1432e4ed7901SPeter Brune 
1433e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunctionNorm()
1434e4ed7901SPeter Brune @*/
1435e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunction(SNES snes, Vec f)
1436e4ed7901SPeter Brune {
1437e4ed7901SPeter Brune   PetscErrorCode ierr;
1438e4ed7901SPeter Brune   Vec            vec_func;
1439e4ed7901SPeter Brune 
1440e4ed7901SPeter Brune   PetscFunctionBegin;
1441e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1442e4ed7901SPeter Brune   PetscValidHeaderSpecific(f,VEC_CLASSID,2);
1443e4ed7901SPeter Brune   PetscCheckSameComm(snes,1,f,2);
1444e4ed7901SPeter Brune   ierr = SNESGetFunction(snes,&vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1445e4ed7901SPeter Brune   ierr = VecCopy(f, vec_func);CHKERRQ(ierr);
1446217b9c2eSPeter Brune   snes->vec_func_init_set = PETSC_TRUE;
1447e4ed7901SPeter Brune   PetscFunctionReturn(0);
1448e4ed7901SPeter Brune }
1449e4ed7901SPeter Brune 
1450e4ed7901SPeter Brune 
1451e4ed7901SPeter Brune #undef __FUNCT__
1452e4ed7901SPeter Brune #define __FUNCT__ "SNESSetInitialFunctionNorm"
1453e4ed7901SPeter Brune /*@C
1454e4ed7901SPeter Brune    SNESSetInitialFunctionNorm - Sets the function norm to be used as the function norm
1455e4ed7901SPeter Brune    at the initialization of the  method.  In some instances, the user has precomputed
1456e4ed7901SPeter Brune    the function and its norm before calling SNESSolve.  This function allows one to
1457e4ed7901SPeter Brune    avoid a redundant call to SNESComputeFunction() and VecNorm() in that case.
1458e4ed7901SPeter Brune 
1459e4ed7901SPeter Brune    Logically Collective on SNES
1460e4ed7901SPeter Brune 
1461e4ed7901SPeter Brune    Input Parameters:
1462e4ed7901SPeter Brune +  snes - the SNES context
1463e4ed7901SPeter Brune -  fnorm - the norm of F as set by SNESSetInitialFunction()
1464e4ed7901SPeter Brune 
1465e4ed7901SPeter Brune    This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning.
1466e4ed7901SPeter Brune 
1467e4ed7901SPeter Brune    Level: developer
1468e4ed7901SPeter Brune 
1469e4ed7901SPeter Brune .keywords: SNES, nonlinear, set, function, norm
1470e4ed7901SPeter Brune 
1471e4ed7901SPeter Brune .seealso: SNESSetFunction(), SNESComputeFunction(), SNESSetInitialFunction()
1472e4ed7901SPeter Brune @*/
1473e4ed7901SPeter Brune PetscErrorCode  SNESSetInitialFunctionNorm(SNES snes, PetscReal fnorm)
1474e4ed7901SPeter Brune {
1475e4ed7901SPeter Brune   PetscFunctionBegin;
1476e4ed7901SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1477e4ed7901SPeter Brune   snes->norm_init = fnorm;
1478e4ed7901SPeter Brune   snes->norm_init_set = PETSC_TRUE;
1479e4ed7901SPeter Brune   PetscFunctionReturn(0);
1480e4ed7901SPeter Brune }
1481e4ed7901SPeter Brune 
1482e4ed7901SPeter Brune #undef __FUNCT__
1483534ebe21SPeter Brune #define __FUNCT__ "SNESSetNormType"
1484534ebe21SPeter Brune /*@
1485534ebe21SPeter Brune    SNESSetNormType - Sets the SNESNormType used in covergence and monitoring
1486534ebe21SPeter Brune    of the SNES method.
1487534ebe21SPeter Brune 
1488534ebe21SPeter Brune    Logically Collective on SNES
1489534ebe21SPeter Brune 
1490534ebe21SPeter Brune    Input Parameters:
1491534ebe21SPeter Brune +  snes - the SNES context
1492534ebe21SPeter Brune -  normtype - the type of the norm used
1493534ebe21SPeter Brune 
1494534ebe21SPeter Brune    Notes:
1495534ebe21SPeter Brune    Only certain SNES methods support certain SNESNormTypes.  Most require evaluation
1496534ebe21SPeter Brune    of the nonlinear function and the taking of its norm at every iteration to
1497534ebe21SPeter Brune    even ensure convergence at all.  However, methods such as custom Gauss-Seidel methods
1498534ebe21SPeter Brune    (SNESGS) and the like do not require the norm of the function to be computed, and therfore
1499534ebe21SPeter Brune    may either be monitored for convergence or not.  As these are often used as nonlinear
1500534ebe21SPeter Brune    preconditioners, monitoring the norm of their error is not a useful enterprise within
1501534ebe21SPeter Brune    their solution.
1502534ebe21SPeter Brune 
1503534ebe21SPeter Brune    Level: developer
1504534ebe21SPeter Brune 
1505534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1506534ebe21SPeter Brune 
1507534ebe21SPeter Brune .seealso: SNESGetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1508534ebe21SPeter Brune @*/
1509534ebe21SPeter Brune PetscErrorCode  SNESSetNormType(SNES snes, SNESNormType normtype)
1510534ebe21SPeter Brune {
1511534ebe21SPeter Brune   PetscFunctionBegin;
1512534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1513534ebe21SPeter Brune   snes->normtype = normtype;
1514534ebe21SPeter Brune   PetscFunctionReturn(0);
1515534ebe21SPeter Brune }
1516534ebe21SPeter Brune 
1517534ebe21SPeter Brune 
1518534ebe21SPeter Brune #undef __FUNCT__
1519534ebe21SPeter Brune #define __FUNCT__ "SNESGetNormType"
1520534ebe21SPeter Brune /*@
1521534ebe21SPeter Brune    SNESGetNormType - Gets the SNESNormType used in covergence and monitoring
1522534ebe21SPeter Brune    of the SNES method.
1523534ebe21SPeter Brune 
1524534ebe21SPeter Brune    Logically Collective on SNES
1525534ebe21SPeter Brune 
1526534ebe21SPeter Brune    Input Parameters:
1527534ebe21SPeter Brune +  snes - the SNES context
1528534ebe21SPeter Brune -  normtype - the type of the norm used
1529534ebe21SPeter Brune 
1530534ebe21SPeter Brune    Level: advanced
1531534ebe21SPeter Brune 
1532534ebe21SPeter Brune .keywords: SNES, nonlinear, set, function, norm, type
1533534ebe21SPeter Brune 
1534534ebe21SPeter Brune .seealso: SNESSetNormType(), SNESComputeFunction(), VecNorm(), SNESSetFunction(), SNESSetInitialFunction(), SNESNormType
1535534ebe21SPeter Brune @*/
1536534ebe21SPeter Brune PetscErrorCode  SNESGetNormType(SNES snes, SNESNormType *normtype)
1537534ebe21SPeter Brune {
1538534ebe21SPeter Brune   PetscFunctionBegin;
1539534ebe21SPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1540534ebe21SPeter Brune   *normtype = snes->normtype;
1541534ebe21SPeter Brune   PetscFunctionReturn(0);
1542534ebe21SPeter Brune }
1543534ebe21SPeter Brune 
1544534ebe21SPeter Brune #undef __FUNCT__
1545646217ecSPeter Brune #define __FUNCT__ "SNESSetGS"
1546c79ef259SPeter Brune /*@C
1547c79ef259SPeter Brune    SNESSetGS - Sets the user nonlinear Gauss-Seidel routine for
1548c79ef259SPeter Brune    use with composed nonlinear solvers.
1549c79ef259SPeter Brune 
1550c79ef259SPeter Brune    Input Parameters:
1551c79ef259SPeter Brune +  snes   - the SNES context
1552c79ef259SPeter Brune .  gsfunc - function evaluation routine
1553c79ef259SPeter Brune -  ctx    - [optional] user-defined context for private data for the
1554c79ef259SPeter Brune             smoother evaluation routine (may be PETSC_NULL)
1555c79ef259SPeter Brune 
1556c79ef259SPeter Brune    Calling sequence of func:
1557c79ef259SPeter Brune $    func (SNES snes,Vec x,Vec b,void *ctx);
1558c79ef259SPeter Brune 
1559c79ef259SPeter Brune +  X   - solution vector
1560c79ef259SPeter Brune .  B   - RHS vector
1561d28543b3SPeter Brune -  ctx - optional user-defined Gauss-Seidel context
1562c79ef259SPeter Brune 
1563c79ef259SPeter Brune    Notes:
1564c79ef259SPeter Brune    The GS routines are used by the composed nonlinear solver to generate
1565c79ef259SPeter Brune     a problem appropriate update to the solution, particularly FAS.
1566c79ef259SPeter Brune 
1567d28543b3SPeter Brune    Level: intermediate
1568c79ef259SPeter Brune 
1569d28543b3SPeter Brune .keywords: SNES, nonlinear, set, Gauss-Seidel
1570c79ef259SPeter Brune 
1571c79ef259SPeter Brune .seealso: SNESGetFunction(), SNESComputeGS()
1572c79ef259SPeter Brune @*/
15736cab3a1bSJed Brown PetscErrorCode SNESSetGS(SNES snes,PetscErrorCode (*gsfunc)(SNES,Vec,Vec,void*),void *ctx)
15746cab3a1bSJed Brown {
15756cab3a1bSJed Brown   PetscErrorCode ierr;
15766cab3a1bSJed Brown   DM dm;
15776cab3a1bSJed Brown 
1578646217ecSPeter Brune   PetscFunctionBegin;
15796cab3a1bSJed Brown   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
15806cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
15816cab3a1bSJed Brown   ierr = DMSNESSetGS(dm,gsfunc,ctx);CHKERRQ(ierr);
1582646217ecSPeter Brune   PetscFunctionReturn(0);
1583646217ecSPeter Brune }
1584646217ecSPeter Brune 
1585d25893d9SBarry Smith #undef __FUNCT__
158689b92e6fSPeter Brune #define __FUNCT__ "SNESSetGSSweeps"
158789b92e6fSPeter Brune /*@
158889b92e6fSPeter Brune    SNESSetGSSweeps - Sets the number of sweeps of GS to use.
158989b92e6fSPeter Brune 
159089b92e6fSPeter Brune    Input Parameters:
159189b92e6fSPeter Brune +  snes   - the SNES context
159289b92e6fSPeter Brune -  sweeps  - the number of sweeps of GS to perform.
159389b92e6fSPeter Brune 
159489b92e6fSPeter Brune    Level: intermediate
159589b92e6fSPeter Brune 
159689b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
159789b92e6fSPeter Brune 
159889b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESGetGSSweeps()
159989b92e6fSPeter Brune @*/
160089b92e6fSPeter Brune 
160189b92e6fSPeter Brune PetscErrorCode SNESSetGSSweeps(SNES snes, PetscInt sweeps) {
160289b92e6fSPeter Brune   PetscFunctionBegin;
160389b92e6fSPeter Brune   snes->gssweeps = sweeps;
160489b92e6fSPeter Brune   PetscFunctionReturn(0);
160589b92e6fSPeter Brune }
160689b92e6fSPeter Brune 
160789b92e6fSPeter Brune 
160889b92e6fSPeter Brune #undef __FUNCT__
160989b92e6fSPeter Brune #define __FUNCT__ "SNESGetGSSweeps"
161089b92e6fSPeter Brune /*@
161189b92e6fSPeter Brune    SNESGetGSSweeps - Gets the number of sweeps GS will use.
161289b92e6fSPeter Brune 
161389b92e6fSPeter Brune    Input Parameters:
161489b92e6fSPeter Brune .  snes   - the SNES context
161589b92e6fSPeter Brune 
161689b92e6fSPeter Brune    Output Parameters:
161789b92e6fSPeter Brune .  sweeps  - the number of sweeps of GS to perform.
161889b92e6fSPeter Brune 
161989b92e6fSPeter Brune    Level: intermediate
162089b92e6fSPeter Brune 
162189b92e6fSPeter Brune .keywords: SNES, nonlinear, set, Gauss-Siedel
162289b92e6fSPeter Brune 
162389b92e6fSPeter Brune .seealso: SNESSetGS(), SNESGetGS(), SNESSetPC(), SNESSetGSSweeps()
162489b92e6fSPeter Brune @*/
162589b92e6fSPeter Brune PetscErrorCode SNESGetGSSweeps(SNES snes, PetscInt * sweeps) {
162689b92e6fSPeter Brune   PetscFunctionBegin;
162789b92e6fSPeter Brune   *sweeps = snes->gssweeps;
162889b92e6fSPeter Brune   PetscFunctionReturn(0);
162989b92e6fSPeter Brune }
163089b92e6fSPeter Brune 
163189b92e6fSPeter Brune #undef __FUNCT__
16328b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeFunction"
16338b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx)
16348b0a5094SBarry Smith {
16358b0a5094SBarry Smith   PetscErrorCode ierr;
16366cab3a1bSJed Brown   void *functx,*jacctx;
16376cab3a1bSJed Brown 
16388b0a5094SBarry Smith   PetscFunctionBegin;
16396cab3a1bSJed Brown   ierr = SNESGetFunction(snes,PETSC_NULL,PETSC_NULL,&functx);CHKERRQ(ierr);
16406cab3a1bSJed Brown   ierr = SNESGetJacobian(snes,PETSC_NULL,PETSC_NULL,PETSC_NULL,&jacctx);CHKERRQ(ierr);
16418b0a5094SBarry Smith   /*  A(x)*x - b(x) */
16426cab3a1bSJed Brown   ierr = (*snes->ops->computepjacobian)(snes,x,&snes->jacobian,&snes->jacobian_pre,&snes->matstruct,jacctx);CHKERRQ(ierr);
16436cab3a1bSJed Brown   ierr = (*snes->ops->computepfunction)(snes,x,f,functx);CHKERRQ(ierr);
16448b0a5094SBarry Smith   ierr = VecView(x,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16458b0a5094SBarry Smith   ierr = VecView(f,PETSC_VIEWER_BINARY_WORLD);CHKERRQ(ierr);
16468b0a5094SBarry Smith   ierr = VecScale(f,-1.0);CHKERRQ(ierr);
16478b0a5094SBarry Smith   ierr = MatMultAdd(snes->jacobian_pre,x,f,f);CHKERRQ(ierr);
16488b0a5094SBarry Smith   PetscFunctionReturn(0);
16498b0a5094SBarry Smith }
16508b0a5094SBarry Smith 
16518b0a5094SBarry Smith #undef __FUNCT__
16528b0a5094SBarry Smith #define __FUNCT__ "SNESPicardComputeJacobian"
16538b0a5094SBarry Smith PetscErrorCode  SNESPicardComputeJacobian(SNES snes,Vec x1,Mat *J,Mat *B,MatStructure *flag,void *ctx)
16548b0a5094SBarry Smith {
16558b0a5094SBarry Smith   PetscFunctionBegin;
16568b0a5094SBarry Smith   *flag = snes->matstruct;
16578b0a5094SBarry Smith   PetscFunctionReturn(0);
16588b0a5094SBarry Smith }
16598b0a5094SBarry Smith 
16608b0a5094SBarry Smith #undef __FUNCT__
16618b0a5094SBarry Smith #define __FUNCT__ "SNESSetPicard"
16628b0a5094SBarry Smith /*@C
16630d04baf8SBarry Smith    SNESSetPicard - Use SNES to solve the semilinear-system A(x) x = b(x) via a Picard type iteration (Picard linearization)
16648b0a5094SBarry Smith 
16658b0a5094SBarry Smith    Logically Collective on SNES
16668b0a5094SBarry Smith 
16678b0a5094SBarry Smith    Input Parameters:
16688b0a5094SBarry Smith +  snes - the SNES context
16698b0a5094SBarry Smith .  r - vector to store function value
16708b0a5094SBarry Smith .  func - function evaluation routine
16718b0a5094SBarry 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)
16728b0a5094SBarry Smith .  mat - matrix to store A
16738b0a5094SBarry Smith .  mfunc  - function to compute matrix value
16748b0a5094SBarry Smith -  ctx - [optional] user-defined context for private data for the
16758b0a5094SBarry Smith          function evaluation routine (may be PETSC_NULL)
16768b0a5094SBarry Smith 
16778b0a5094SBarry Smith    Calling sequence of func:
16788b0a5094SBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
16798b0a5094SBarry Smith 
16808b0a5094SBarry Smith +  f - function vector
16818b0a5094SBarry Smith -  ctx - optional user-defined function context
16828b0a5094SBarry Smith 
16838b0a5094SBarry Smith    Calling sequence of mfunc:
16848b0a5094SBarry Smith $     mfunc (SNES snes,Vec x,Mat *jmat,Mat *mat,int *flag,void *ctx);
16858b0a5094SBarry Smith 
16868b0a5094SBarry Smith +  x - input vector
16878b0a5094SBarry 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(),
16888b0a5094SBarry Smith           normally just pass mat in this location
16898b0a5094SBarry Smith .  mat - form A(x) matrix
16908b0a5094SBarry Smith .  flag - flag indicating information about the preconditioner matrix
16918b0a5094SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
16928b0a5094SBarry Smith -  ctx - [optional] user-defined Jacobian context
16938b0a5094SBarry Smith 
16948b0a5094SBarry Smith    Notes:
16958b0a5094SBarry Smith     One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both
16968b0a5094SBarry Smith 
16978b0a5094SBarry 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}
16988b0a5094SBarry 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.
16998b0a5094SBarry Smith 
17008b0a5094SBarry Smith      Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner.
17018b0a5094SBarry Smith 
17020d04baf8SBarry Smith    We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then
17030d04baf8SBarry Smith    the direct Picard iteration A(x^n) x^{n+1} = b(x^n)
17048b0a5094SBarry Smith 
17058b0a5094SBarry 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
17068b0a5094SBarry 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
17078b0a5094SBarry Smith    different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-).
17088b0a5094SBarry Smith 
17098b0a5094SBarry Smith    Level: beginner
17108b0a5094SBarry Smith 
17118b0a5094SBarry Smith .keywords: SNES, nonlinear, set, function
17128b0a5094SBarry Smith 
17130d04baf8SBarry Smith .seealso: SNESGetFunction(), SNESSetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESGetPicard(), SNESLineSearchPreCheckPicard()
17148b0a5094SBarry Smith @*/
17158b0a5094SBarry 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)
17168b0a5094SBarry Smith {
17178b0a5094SBarry Smith   PetscErrorCode ierr;
17188b0a5094SBarry Smith   PetscFunctionBegin;
17198b0a5094SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17208b0a5094SBarry Smith   snes->ops->computepfunction = func;
17218b0a5094SBarry Smith   snes->ops->computepjacobian = mfunc;
17228b0a5094SBarry Smith   ierr = SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx);CHKERRQ(ierr);
17238b0a5094SBarry Smith   ierr = SNESSetJacobian(snes,jmat,mat,SNESPicardComputeJacobian,ctx);CHKERRQ(ierr);
17248b0a5094SBarry Smith   PetscFunctionReturn(0);
17258b0a5094SBarry Smith }
17268b0a5094SBarry Smith 
17278b0a5094SBarry Smith #undef __FUNCT__
1728d25893d9SBarry Smith #define __FUNCT__ "SNESSetComputeInitialGuess"
1729d25893d9SBarry Smith /*@C
1730d25893d9SBarry Smith    SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1731d25893d9SBarry Smith 
1732d25893d9SBarry Smith    Logically Collective on SNES
1733d25893d9SBarry Smith 
1734d25893d9SBarry Smith    Input Parameters:
1735d25893d9SBarry Smith +  snes - the SNES context
1736d25893d9SBarry Smith .  func - function evaluation routine
1737d25893d9SBarry Smith -  ctx - [optional] user-defined context for private data for the
1738d25893d9SBarry Smith          function evaluation routine (may be PETSC_NULL)
1739d25893d9SBarry Smith 
1740d25893d9SBarry Smith    Calling sequence of func:
1741d25893d9SBarry Smith $    func (SNES snes,Vec x,void *ctx);
1742d25893d9SBarry Smith 
1743d25893d9SBarry Smith .  f - function vector
1744d25893d9SBarry Smith -  ctx - optional user-defined function context
1745d25893d9SBarry Smith 
1746d25893d9SBarry Smith    Level: intermediate
1747d25893d9SBarry Smith 
1748d25893d9SBarry Smith .keywords: SNES, nonlinear, set, function
1749d25893d9SBarry Smith 
1750d25893d9SBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1751d25893d9SBarry Smith @*/
1752d25893d9SBarry Smith PetscErrorCode  SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1753d25893d9SBarry Smith {
1754d25893d9SBarry Smith   PetscFunctionBegin;
1755d25893d9SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1756d25893d9SBarry Smith   if (func) snes->ops->computeinitialguess = func;
1757d25893d9SBarry Smith   if (ctx)  snes->initialguessP            = ctx;
1758d25893d9SBarry Smith   PetscFunctionReturn(0);
1759d25893d9SBarry Smith }
1760d25893d9SBarry Smith 
17613ab0aad5SBarry Smith /* --------------------------------------------------------------- */
17623ab0aad5SBarry Smith #undef __FUNCT__
17631096aae1SMatthew Knepley #define __FUNCT__ "SNESGetRhs"
17641096aae1SMatthew Knepley /*@C
17651096aae1SMatthew Knepley    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
17661096aae1SMatthew Knepley    it assumes a zero right hand side.
17671096aae1SMatthew Knepley 
17683f9fe445SBarry Smith    Logically Collective on SNES
17691096aae1SMatthew Knepley 
17701096aae1SMatthew Knepley    Input Parameter:
17711096aae1SMatthew Knepley .  snes - the SNES context
17721096aae1SMatthew Knepley 
17731096aae1SMatthew Knepley    Output Parameter:
1774bc08b0f1SBarry Smith .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
17751096aae1SMatthew Knepley 
17761096aae1SMatthew Knepley    Level: intermediate
17771096aae1SMatthew Knepley 
17781096aae1SMatthew Knepley .keywords: SNES, nonlinear, get, function, right hand side
17791096aae1SMatthew Knepley 
178085385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
17811096aae1SMatthew Knepley @*/
17827087cfbeSBarry Smith PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
17831096aae1SMatthew Knepley {
17841096aae1SMatthew Knepley   PetscFunctionBegin;
17850700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
17861096aae1SMatthew Knepley   PetscValidPointer(rhs,2);
178785385478SLisandro Dalcin   *rhs = snes->vec_rhs;
17881096aae1SMatthew Knepley   PetscFunctionReturn(0);
17891096aae1SMatthew Knepley }
17901096aae1SMatthew Knepley 
17911096aae1SMatthew Knepley #undef __FUNCT__
17924a2ae208SSatish Balay #define __FUNCT__ "SNESComputeFunction"
17939b94acceSBarry Smith /*@
179436851e7fSLois Curfman McInnes    SNESComputeFunction - Calls the function that has been set with
17959b94acceSBarry Smith                          SNESSetFunction().
17969b94acceSBarry Smith 
1797c7afd0dbSLois Curfman McInnes    Collective on SNES
1798c7afd0dbSLois Curfman McInnes 
17999b94acceSBarry Smith    Input Parameters:
1800c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1801c7afd0dbSLois Curfman McInnes -  x - input vector
18029b94acceSBarry Smith 
18039b94acceSBarry Smith    Output Parameter:
18043638b69dSLois Curfman McInnes .  y - function vector, as set by SNESSetFunction()
18059b94acceSBarry Smith 
18061bffabb2SLois Curfman McInnes    Notes:
180736851e7fSLois Curfman McInnes    SNESComputeFunction() is typically used within nonlinear solvers
180836851e7fSLois Curfman McInnes    implementations, so most users would not generally call this routine
180936851e7fSLois Curfman McInnes    themselves.
181036851e7fSLois Curfman McInnes 
181136851e7fSLois Curfman McInnes    Level: developer
181236851e7fSLois Curfman McInnes 
18139b94acceSBarry Smith .keywords: SNES, nonlinear, compute, function
18149b94acceSBarry Smith 
1815a86d99e1SLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetFunction()
18169b94acceSBarry Smith @*/
18177087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
18189b94acceSBarry Smith {
1819dfbe8321SBarry Smith   PetscErrorCode ierr;
18206cab3a1bSJed Brown   DM             dm;
18216cab3a1bSJed Brown   SNESDM         sdm;
18229b94acceSBarry Smith 
18233a40ed3dSBarry Smith   PetscFunctionBegin;
18240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
18250700a824SBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
18260700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
1827c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,x,2);
1828c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,3);
18294ec14c9cSBarry Smith   VecValidValues(x,2,PETSC_TRUE);
1830184914b5SBarry Smith 
18316cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18326cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
1833d5ba7fb7SMatthew Knepley   ierr = PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18346cab3a1bSJed Brown   if (sdm->computefunction) {
1835d64ed03dSBarry Smith     PetscStackPush("SNES user function");
18366cab3a1bSJed Brown     ierr = (*sdm->computefunction)(snes,x,y,sdm->functionctx);CHKERRQ(ierr);
1837d64ed03dSBarry Smith     PetscStackPop;
183873250ac0SBarry Smith   } else if (snes->dm) {
1839644e2e5bSBarry Smith     ierr = DMComputeFunction(snes->dm,x,y);CHKERRQ(ierr);
1840c90fad12SPeter Brune   } else if (snes->vec_rhs) {
1841c90fad12SPeter Brune     ierr = MatMult(snes->jacobian, x, y);CHKERRQ(ierr);
1842644e2e5bSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
184385385478SLisandro Dalcin   if (snes->vec_rhs) {
184485385478SLisandro Dalcin     ierr = VecAXPY(y,-1.0,snes->vec_rhs);CHKERRQ(ierr);
18453ab0aad5SBarry Smith   }
1846ae3c334cSLois Curfman McInnes   snes->nfuncs++;
1847d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(ierr);
18484ec14c9cSBarry Smith   VecValidValues(y,3,PETSC_FALSE);
18493a40ed3dSBarry Smith   PetscFunctionReturn(0);
18509b94acceSBarry Smith }
18519b94acceSBarry Smith 
18524a2ae208SSatish Balay #undef __FUNCT__
1853646217ecSPeter Brune #define __FUNCT__ "SNESComputeGS"
1854c79ef259SPeter Brune /*@
1855c79ef259SPeter Brune    SNESComputeGS - Calls the Gauss-Seidel function that has been set with
1856c79ef259SPeter Brune                    SNESSetGS().
1857c79ef259SPeter Brune 
1858c79ef259SPeter Brune    Collective on SNES
1859c79ef259SPeter Brune 
1860c79ef259SPeter Brune    Input Parameters:
1861c79ef259SPeter Brune +  snes - the SNES context
1862c79ef259SPeter Brune .  x - input vector
1863c79ef259SPeter Brune -  b - rhs vector
1864c79ef259SPeter Brune 
1865c79ef259SPeter Brune    Output Parameter:
1866c79ef259SPeter Brune .  x - new solution vector
1867c79ef259SPeter Brune 
1868c79ef259SPeter Brune    Notes:
1869c79ef259SPeter Brune    SNESComputeGS() is typically used within composed nonlinear solver
1870c79ef259SPeter Brune    implementations, so most users would not generally call this routine
1871c79ef259SPeter Brune    themselves.
1872c79ef259SPeter Brune 
1873c79ef259SPeter Brune    Level: developer
1874c79ef259SPeter Brune 
1875c79ef259SPeter Brune .keywords: SNES, nonlinear, compute, function
1876c79ef259SPeter Brune 
1877c79ef259SPeter Brune .seealso: SNESSetGS(), SNESComputeFunction()
1878c79ef259SPeter Brune @*/
1879646217ecSPeter Brune PetscErrorCode  SNESComputeGS(SNES snes,Vec b,Vec x)
1880646217ecSPeter Brune {
1881646217ecSPeter Brune   PetscErrorCode ierr;
188289b92e6fSPeter Brune   PetscInt i;
18836cab3a1bSJed Brown   DM dm;
18846cab3a1bSJed Brown   SNESDM sdm;
1885646217ecSPeter Brune 
1886646217ecSPeter Brune   PetscFunctionBegin;
1887646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
1888646217ecSPeter Brune   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
1889646217ecSPeter Brune   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,3);
1890646217ecSPeter Brune   PetscCheckSameComm(snes,1,x,2);
1891646217ecSPeter Brune   if(b) PetscCheckSameComm(snes,1,b,3);
18924ec14c9cSBarry Smith   if (b) VecValidValues(b,2,PETSC_TRUE);
1893701cf23dSPeter Brune   ierr = PetscLogEventBegin(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
18946cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
18956cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
18966cab3a1bSJed Brown   if (sdm->computegs) {
189789b92e6fSPeter Brune     for (i = 0; i < snes->gssweeps; i++) {
1898646217ecSPeter Brune       PetscStackPush("SNES user GS");
18996cab3a1bSJed Brown       ierr = (*sdm->computegs)(snes,x,b,sdm->gsctx);CHKERRQ(ierr);
1900646217ecSPeter Brune       PetscStackPop;
190189b92e6fSPeter Brune     }
1902646217ecSPeter Brune   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetGS() before SNESComputeGS(), likely called from SNESSolve().");
1903701cf23dSPeter Brune   ierr = PetscLogEventEnd(SNES_GSEval,snes,x,b,0);CHKERRQ(ierr);
19044ec14c9cSBarry Smith   VecValidValues(x,3,PETSC_FALSE);
1905646217ecSPeter Brune   PetscFunctionReturn(0);
1906646217ecSPeter Brune }
1907646217ecSPeter Brune 
1908646217ecSPeter Brune 
1909646217ecSPeter Brune #undef __FUNCT__
19104a2ae208SSatish Balay #define __FUNCT__ "SNESComputeJacobian"
191162fef451SLois Curfman McInnes /*@
191262fef451SLois Curfman McInnes    SNESComputeJacobian - Computes the Jacobian matrix that has been
191362fef451SLois Curfman McInnes    set with SNESSetJacobian().
191462fef451SLois Curfman McInnes 
1915c7afd0dbSLois Curfman McInnes    Collective on SNES and Mat
1916c7afd0dbSLois Curfman McInnes 
191762fef451SLois Curfman McInnes    Input Parameters:
1918c7afd0dbSLois Curfman McInnes +  snes - the SNES context
1919c7afd0dbSLois Curfman McInnes -  x - input vector
192062fef451SLois Curfman McInnes 
192162fef451SLois Curfman McInnes    Output Parameters:
1922c7afd0dbSLois Curfman McInnes +  A - Jacobian matrix
192362fef451SLois Curfman McInnes .  B - optional preconditioning matrix
19242b668275SBarry Smith -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1925fee21e36SBarry Smith 
1926e35cf81dSBarry Smith   Options Database Keys:
1927e35cf81dSBarry Smith +    -snes_lag_preconditioner <lag>
1928693365a8SJed Brown .    -snes_lag_jacobian <lag>
1929693365a8SJed Brown .    -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1930693365a8SJed Brown .    -snes_compare_explicit_draw  - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1931693365a8SJed Brown .    -snes_compare_explicit_contour  - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
19324c30e9fbSJed Brown .    -snes_compare_operator  - Make the comparison options above use the operator instead of the preconditioning matrix
1933c01495d3SJed Brown .    -snes_compare_coloring - Compute the finite differece Jacobian using coloring and display norms of difference
1934c01495d3SJed Brown .    -snes_compare_coloring_display - Compute the finite differece Jacobian using coloring and display verbose differences
1935c01495d3SJed Brown .    -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold
1936c01495d3SJed Brown .    -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
1937c01495d3SJed Brown .    -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold
19384c30e9fbSJed Brown .    -snes_compare_coloring_draw - Compute the finite differece Jacobian using coloring and draw differences
1939c01495d3SJed Brown -    -snes_compare_coloring_draw_contour - Compute the finite differece Jacobian using coloring and show contours of matrices and differences
1940c01495d3SJed Brown 
1941e35cf81dSBarry Smith 
194262fef451SLois Curfman McInnes    Notes:
194362fef451SLois Curfman McInnes    Most users should not need to explicitly call this routine, as it
194462fef451SLois Curfman McInnes    is used internally within the nonlinear solvers.
194562fef451SLois Curfman McInnes 
194694b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the
1947dc5a77f8SLois Curfman McInnes    flag parameter.
194862fef451SLois Curfman McInnes 
194936851e7fSLois Curfman McInnes    Level: developer
195036851e7fSLois Curfman McInnes 
195162fef451SLois Curfman McInnes .keywords: SNES, compute, Jacobian, matrix
195262fef451SLois Curfman McInnes 
1953e35cf81dSBarry Smith .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
195462fef451SLois Curfman McInnes @*/
19557087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
19569b94acceSBarry Smith {
1957dfbe8321SBarry Smith   PetscErrorCode ierr;
1958ace3abfcSBarry Smith   PetscBool      flag;
19596cab3a1bSJed Brown   DM             dm;
19606cab3a1bSJed Brown   SNESDM         sdm;
19613a40ed3dSBarry Smith 
19623a40ed3dSBarry Smith   PetscFunctionBegin;
19630700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
19640700a824SBarry Smith   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
19654482741eSBarry Smith   PetscValidPointer(flg,5);
1966c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,X,2);
19674ec14c9cSBarry Smith   VecValidValues(X,2,PETSC_TRUE);
19686cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
19696cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
19706cab3a1bSJed Brown   if (!sdm->computejacobian) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc");
1971ebd3b9afSBarry Smith 
1972ebd3b9afSBarry Smith   /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1973ebd3b9afSBarry Smith 
1974fe3ffe1eSBarry Smith   if (snes->lagjacobian == -2) {
1975fe3ffe1eSBarry Smith     snes->lagjacobian = -1;
1976fe3ffe1eSBarry Smith     ierr = PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");CHKERRQ(ierr);
1977fe3ffe1eSBarry Smith   } else if (snes->lagjacobian == -1) {
1978e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1979e35cf81dSBarry Smith     ierr = PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");CHKERRQ(ierr);
1980251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1981ebd3b9afSBarry Smith     if (flag) {
1982ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1983ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1984ebd3b9afSBarry Smith     }
1985e35cf81dSBarry Smith     PetscFunctionReturn(0);
1986e35cf81dSBarry Smith   } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1987e35cf81dSBarry Smith     *flg = SAME_PRECONDITIONER;
1988e35cf81dSBarry Smith     ierr = PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);CHKERRQ(ierr);
1989251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)*A,MATMFFD,&flag);CHKERRQ(ierr);
1990ebd3b9afSBarry Smith     if (flag) {
1991ebd3b9afSBarry Smith       ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1992ebd3b9afSBarry Smith       ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
1993ebd3b9afSBarry Smith     }
1994e35cf81dSBarry Smith     PetscFunctionReturn(0);
1995e35cf81dSBarry Smith   }
1996e35cf81dSBarry Smith 
1997c4fc05e7SBarry Smith   *flg = DIFFERENT_NONZERO_PATTERN;
1998e35cf81dSBarry Smith   ierr = PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
1999d64ed03dSBarry Smith   PetscStackPush("SNES user Jacobian function");
20006cab3a1bSJed Brown   ierr = (*sdm->computejacobian)(snes,X,A,B,flg,sdm->jacobianctx);CHKERRQ(ierr);
2001d64ed03dSBarry Smith   PetscStackPop;
2002d5ba7fb7SMatthew Knepley   ierr = PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);CHKERRQ(ierr);
2003a8054027SBarry Smith 
20043b4f5425SBarry Smith   if (snes->lagpreconditioner == -2) {
20053b4f5425SBarry Smith     ierr = PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");CHKERRQ(ierr);
20063b4f5425SBarry Smith     snes->lagpreconditioner = -1;
20073b4f5425SBarry Smith   } else if (snes->lagpreconditioner == -1) {
2008a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2009a8054027SBarry Smith     ierr = PetscInfo(snes,"Reusing preconditioner because lag is -1\n");CHKERRQ(ierr);
2010a8054027SBarry Smith   } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
2011a8054027SBarry Smith     *flg = SAME_PRECONDITIONER;
2012a8054027SBarry Smith     ierr = PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);CHKERRQ(ierr);
2013a8054027SBarry Smith   }
2014a8054027SBarry Smith 
20156d84be18SBarry Smith   /* make sure user returned a correct Jacobian and preconditioner */
20160700a824SBarry Smith   /* PetscValidHeaderSpecific(*A,MAT_CLASSID,3);
20170700a824SBarry Smith     PetscValidHeaderSpecific(*B,MAT_CLASSID,4);   */
2018693365a8SJed Brown   {
2019693365a8SJed Brown     PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
2020693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);CHKERRQ(ierr);
2021693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
2022693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
2023693365a8SJed Brown     ierr  = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);CHKERRQ(ierr);
2024693365a8SJed Brown     if (flag || flag_draw || flag_contour) {
2025693365a8SJed Brown       Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
2026693365a8SJed Brown       MatStructure mstruct;
2027693365a8SJed Brown       PetscViewer vdraw,vstdout;
20286b3a5b13SJed Brown       PetscBool flg;
2029693365a8SJed Brown       if (flag_operator) {
2030693365a8SJed Brown         ierr = MatComputeExplicitOperator(*A,&Bexp_mine);CHKERRQ(ierr);
2031693365a8SJed Brown         Bexp = Bexp_mine;
2032693365a8SJed Brown       } else {
2033693365a8SJed Brown         /* See if the preconditioning matrix can be viewed and added directly */
2034251f4c67SDmitry Karpeev         ierr = PetscObjectTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");CHKERRQ(ierr);
2035693365a8SJed Brown         if (flg) Bexp = *B;
2036693365a8SJed Brown         else {
2037693365a8SJed Brown           /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
2038693365a8SJed Brown           ierr = MatComputeExplicitOperator(*B,&Bexp_mine);CHKERRQ(ierr);
2039693365a8SJed Brown           Bexp = Bexp_mine;
2040693365a8SJed Brown         }
2041693365a8SJed Brown       }
2042693365a8SJed Brown       ierr = MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);CHKERRQ(ierr);
2043693365a8SJed Brown       ierr = SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);CHKERRQ(ierr);
2044693365a8SJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
2045693365a8SJed Brown       if (flag_draw || flag_contour) {
2046693365a8SJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
2047693365a8SJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
2048693365a8SJed Brown       } else vdraw = PETSC_NULL;
2049693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");CHKERRQ(ierr);
2050693365a8SJed Brown       if (flag) {ierr = MatView(Bexp,vstdout);CHKERRQ(ierr);}
2051693365a8SJed Brown       if (vdraw) {ierr = MatView(Bexp,vdraw);CHKERRQ(ierr);}
2052693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");CHKERRQ(ierr);
2053693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2054693365a8SJed Brown       if (vdraw) {ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);}
2055693365a8SJed Brown       ierr = MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
2056693365a8SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");CHKERRQ(ierr);
2057693365a8SJed Brown       if (flag) {ierr = MatView(FDexp,vstdout);CHKERRQ(ierr);}
2058693365a8SJed Brown       if (vdraw) {              /* Always use contour for the difference */
2059693365a8SJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
2060693365a8SJed Brown         ierr = MatView(FDexp,vdraw);CHKERRQ(ierr);
2061693365a8SJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
2062693365a8SJed Brown       }
2063693365a8SJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
2064693365a8SJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
2065693365a8SJed Brown       ierr = MatDestroy(&Bexp_mine);CHKERRQ(ierr);
2066693365a8SJed Brown       ierr = MatDestroy(&FDexp);CHKERRQ(ierr);
2067693365a8SJed Brown     }
2068693365a8SJed Brown   }
20694c30e9fbSJed Brown   {
20706719d8e4SJed Brown     PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE;
20716719d8e4SJed Brown     PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON;
20724c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring",&flag,PETSC_NULL);CHKERRQ(ierr);
20736719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_display",&flag_display,PETSC_NULL);CHKERRQ(ierr);
20744c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",&flag_draw,PETSC_NULL);CHKERRQ(ierr);
20754c30e9fbSJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",&flag_contour,PETSC_NULL);CHKERRQ(ierr);
20766719d8e4SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",&flag_threshold,PETSC_NULL);CHKERRQ(ierr);
20776719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,PETSC_NULL);CHKERRQ(ierr);
20786719d8e4SJed Brown     ierr = PetscOptionsGetReal(((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,PETSC_NULL);CHKERRQ(ierr);
20796719d8e4SJed Brown     if (flag || flag_display || flag_draw || flag_contour || flag_threshold) {
20804c30e9fbSJed Brown       Mat Bfd;
20814c30e9fbSJed Brown       MatStructure mstruct;
20824c30e9fbSJed Brown       PetscViewer vdraw,vstdout;
20834c30e9fbSJed Brown       ISColoring iscoloring;
20844c30e9fbSJed Brown       MatFDColoring matfdcoloring;
20854c30e9fbSJed Brown       PetscErrorCode (*func)(SNES,Vec,Vec,void*);
20864c30e9fbSJed Brown       void *funcctx;
20876719d8e4SJed Brown       PetscReal norm1,norm2,normmax;
20884c30e9fbSJed Brown 
20894c30e9fbSJed Brown       ierr = MatDuplicate(*B,MAT_DO_NOT_COPY_VALUES,&Bfd);CHKERRQ(ierr);
20904c30e9fbSJed Brown       ierr = MatGetColoring(Bfd,MATCOLORINGSL,&iscoloring);CHKERRQ(ierr);
20914c30e9fbSJed Brown       ierr = MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring);CHKERRQ(ierr);
20924c30e9fbSJed Brown       ierr = ISColoringDestroy(&iscoloring);CHKERRQ(ierr);
20934c30e9fbSJed Brown 
20944c30e9fbSJed Brown       /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */
20954c30e9fbSJed Brown       ierr = SNESGetFunction(snes,PETSC_NULL,&func,&funcctx);CHKERRQ(ierr);
20964c30e9fbSJed Brown       ierr = MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode(*)(void))func,funcctx);CHKERRQ(ierr);
20974c30e9fbSJed Brown       ierr = PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix);CHKERRQ(ierr);
20984c30e9fbSJed Brown       ierr = PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_");CHKERRQ(ierr);
20994c30e9fbSJed Brown       ierr = MatFDColoringSetFromOptions(matfdcoloring);CHKERRQ(ierr);
21004c30e9fbSJed Brown       ierr = MatFDColoringApply(Bfd,matfdcoloring,X,&mstruct,snes);CHKERRQ(ierr);
21014c30e9fbSJed Brown       ierr = MatFDColoringDestroy(&matfdcoloring);CHKERRQ(ierr);
21024c30e9fbSJed Brown 
21034c30e9fbSJed Brown       ierr = PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);CHKERRQ(ierr);
21044c30e9fbSJed Brown       if (flag_draw || flag_contour) {
21054c30e9fbSJed Brown         ierr = PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);CHKERRQ(ierr);
21064c30e9fbSJed Brown         if (flag_contour) {ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);}
21074c30e9fbSJed Brown       } else vdraw = PETSC_NULL;
21084c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n");CHKERRQ(ierr);
21096719d8e4SJed Brown       if (flag_display) {ierr = MatView(*B,vstdout);CHKERRQ(ierr);}
21104c30e9fbSJed Brown       if (vdraw) {ierr = MatView(*B,vdraw);CHKERRQ(ierr);}
21114c30e9fbSJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n");CHKERRQ(ierr);
21126719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21134c30e9fbSJed Brown       if (vdraw) {ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);}
21144c30e9fbSJed Brown       ierr = MatAYPX(Bfd,-1.0,*B,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
21154c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_1,&norm1);CHKERRQ(ierr);
21166719d8e4SJed Brown       ierr = MatNorm(Bfd,NORM_FROBENIUS,&norm2);CHKERRQ(ierr);
21174c30e9fbSJed Brown       ierr = MatNorm(Bfd,NORM_MAX,&normmax);CHKERRQ(ierr);
21186719d8e4SJed Brown       ierr = PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%G normFrob=%G normmax=%G\n",norm1,norm2,normmax);CHKERRQ(ierr);
21196719d8e4SJed Brown       if (flag_display) {ierr = MatView(Bfd,vstdout);CHKERRQ(ierr);}
21204c30e9fbSJed Brown       if (vdraw) {              /* Always use contour for the difference */
21214c30e9fbSJed Brown         ierr = PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);CHKERRQ(ierr);
21224c30e9fbSJed Brown         ierr = MatView(Bfd,vdraw);CHKERRQ(ierr);
21234c30e9fbSJed Brown         ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);
21244c30e9fbSJed Brown       }
21254c30e9fbSJed Brown       if (flag_contour) {ierr = PetscViewerPopFormat(vdraw);CHKERRQ(ierr);}
21266719d8e4SJed Brown 
21276719d8e4SJed Brown       if (flag_threshold) {
21286719d8e4SJed Brown         PetscInt bs,rstart,rend,i;
21296719d8e4SJed Brown         ierr = MatGetBlockSize(*B,&bs);CHKERRQ(ierr);
21306719d8e4SJed Brown         ierr = MatGetOwnershipRange(*B,&rstart,&rend);CHKERRQ(ierr);
21316719d8e4SJed Brown         for (i=rstart; i<rend; i++) {
21326719d8e4SJed Brown           const PetscScalar *ba,*ca;
21336719d8e4SJed Brown           const PetscInt *bj,*cj;
21346719d8e4SJed Brown           PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1;
21356719d8e4SJed Brown           PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0;
21366719d8e4SJed Brown           ierr = MatGetRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21376719d8e4SJed Brown           ierr = MatGetRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21386719d8e4SJed Brown           if (bn != cn) SETERRQ(((PetscObject)*A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold");
21396719d8e4SJed Brown           for (j=0; j<bn; j++) {
21406719d8e4SJed Brown             PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21416719d8e4SJed Brown             if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) {
21426719d8e4SJed Brown               maxentrycol = bj[j];
21436719d8e4SJed Brown               maxentry = PetscRealPart(ba[j]);
21446719d8e4SJed Brown             }
21456719d8e4SJed Brown             if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) {
21466719d8e4SJed Brown               maxdiffcol = bj[j];
21476719d8e4SJed Brown               maxdiff = PetscRealPart(ca[j]);
21486719d8e4SJed Brown             }
21496719d8e4SJed Brown             if (rdiff > maxrdiff) {
21506719d8e4SJed Brown               maxrdiffcol = bj[j];
21516719d8e4SJed Brown               maxrdiff = rdiff;
21526719d8e4SJed Brown             }
21536719d8e4SJed Brown           }
21546719d8e4SJed Brown           if (maxrdiff > 1) {
21556719d8e4SJed 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);
21566719d8e4SJed Brown             for (j=0; j<bn; j++) {
21576719d8e4SJed Brown               PetscReal rdiff;
21586719d8e4SJed Brown               rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j]));
21596719d8e4SJed Brown               if (rdiff > 1) {
21606719d8e4SJed Brown                 ierr = PetscViewerASCIIPrintf(vstdout," (%D,%G:%G)",bj[j],PetscRealPart(ba[j]),PetscRealPart(ca[j]));CHKERRQ(ierr);
21616719d8e4SJed Brown               }
21626719d8e4SJed Brown             }
21636719d8e4SJed Brown             ierr = PetscViewerASCIIPrintf(vstdout,"\n",i,maxentry,maxdiff,maxrdiff);CHKERRQ(ierr);
21646719d8e4SJed Brown           }
21656719d8e4SJed Brown           ierr = MatRestoreRow(*B,i,&bn,&bj,&ba);CHKERRQ(ierr);
21666719d8e4SJed Brown           ierr = MatRestoreRow(Bfd,i,&cn,&cj,&ca);CHKERRQ(ierr);
21676719d8e4SJed Brown         }
21686719d8e4SJed Brown       }
21694c30e9fbSJed Brown       ierr = PetscViewerDestroy(&vdraw);CHKERRQ(ierr);
21704c30e9fbSJed Brown       ierr = MatDestroy(&Bfd);CHKERRQ(ierr);
21714c30e9fbSJed Brown     }
21724c30e9fbSJed Brown   }
21733a40ed3dSBarry Smith   PetscFunctionReturn(0);
21749b94acceSBarry Smith }
21759b94acceSBarry Smith 
21764a2ae208SSatish Balay #undef __FUNCT__
21774a2ae208SSatish Balay #define __FUNCT__ "SNESSetJacobian"
21789b94acceSBarry Smith /*@C
21799b94acceSBarry Smith    SNESSetJacobian - Sets the function to compute Jacobian as well as the
2180044dda88SLois Curfman McInnes    location to store the matrix.
21819b94acceSBarry Smith 
21823f9fe445SBarry Smith    Logically Collective on SNES and Mat
2183c7afd0dbSLois Curfman McInnes 
21849b94acceSBarry Smith    Input Parameters:
2185c7afd0dbSLois Curfman McInnes +  snes - the SNES context
21869b94acceSBarry Smith .  A - Jacobian matrix
21879b94acceSBarry Smith .  B - preconditioner matrix (usually same as the Jacobian)
2188efd51863SBarry Smith .  func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
2189c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined context for private data for the
2190efd51863SBarry Smith          Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
21919b94acceSBarry Smith 
21929b94acceSBarry Smith    Calling sequence of func:
21938d76a1e5SLois Curfman McInnes $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
21949b94acceSBarry Smith 
2195c7afd0dbSLois Curfman McInnes +  x - input vector
21969b94acceSBarry Smith .  A - Jacobian matrix
21979b94acceSBarry Smith .  B - preconditioner matrix, usually the same as A
2198ac21db08SLois Curfman McInnes .  flag - flag indicating information about the preconditioner matrix
21992b668275SBarry Smith    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
2200c7afd0dbSLois Curfman McInnes -  ctx - [optional] user-defined Jacobian context
22019b94acceSBarry Smith 
22029b94acceSBarry Smith    Notes:
220394b7f48cSBarry Smith    See KSPSetOperators() for important information about setting the flag
22042cd2dfdcSLois Curfman McInnes    output parameter in the routine func().  Be sure to read this information!
2205ac21db08SLois Curfman McInnes 
2206ac21db08SLois Curfman McInnes    The routine func() takes Mat * as the matrix arguments rather than Mat.
22079b94acceSBarry Smith    This allows the Jacobian evaluation routine to replace A and/or B with a
22089b94acceSBarry Smith    completely new new matrix structure (not just different matrix elements)
22099b94acceSBarry Smith    when appropriate, for instance, if the nonzero structure is changing
22109b94acceSBarry Smith    throughout the global iterations.
22119b94acceSBarry Smith 
221216913363SBarry Smith    If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
221316913363SBarry Smith    each matrix.
221416913363SBarry Smith 
2215a8a26c1eSJed Brown    If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
2216a8a26c1eSJed Brown    must be a MatFDColoring.
2217a8a26c1eSJed Brown 
2218c3cc8fd1SJed Brown    Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian.  One common
2219c3cc8fd1SJed Brown    example is to use the "Picard linearization" which only differentiates through the highest order parts of each term.
2220c3cc8fd1SJed Brown 
222136851e7fSLois Curfman McInnes    Level: beginner
222236851e7fSLois Curfman McInnes 
22239b94acceSBarry Smith .keywords: SNES, nonlinear, set, Jacobian, matrix
22249b94acceSBarry Smith 
22253ec795f1SBarry Smith .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
22269b94acceSBarry Smith @*/
22277087cfbeSBarry Smith PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
22289b94acceSBarry Smith {
2229dfbe8321SBarry Smith   PetscErrorCode ierr;
22306cab3a1bSJed Brown   DM             dm;
22313a7fca6bSBarry Smith 
22323a40ed3dSBarry Smith   PetscFunctionBegin;
22330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
22340700a824SBarry Smith   if (A) PetscValidHeaderSpecific(A,MAT_CLASSID,2);
22350700a824SBarry Smith   if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
2236c9780b6fSBarry Smith   if (A) PetscCheckSameComm(snes,1,A,2);
223706975374SJed Brown   if (B) PetscCheckSameComm(snes,1,B,3);
22386cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22396cab3a1bSJed Brown   ierr = DMSNESSetJacobian(dm,func,ctx);CHKERRQ(ierr);
22403a7fca6bSBarry Smith   if (A) {
22417dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
22426bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
22439b94acceSBarry Smith     snes->jacobian = A;
22443a7fca6bSBarry Smith   }
22453a7fca6bSBarry Smith   if (B) {
22467dcf0eaaSdalcinl     ierr = PetscObjectReference((PetscObject)B);CHKERRQ(ierr);
22476bf464f9SBarry Smith     ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
22489b94acceSBarry Smith     snes->jacobian_pre = B;
22493a7fca6bSBarry Smith   }
22503a40ed3dSBarry Smith   PetscFunctionReturn(0);
22519b94acceSBarry Smith }
225262fef451SLois Curfman McInnes 
22534a2ae208SSatish Balay #undef __FUNCT__
22544a2ae208SSatish Balay #define __FUNCT__ "SNESGetJacobian"
2255c2aafc4cSSatish Balay /*@C
2256b4fd4287SBarry Smith    SNESGetJacobian - Returns the Jacobian matrix and optionally the user
2257b4fd4287SBarry Smith    provided context for evaluating the Jacobian.
2258b4fd4287SBarry Smith 
2259c7afd0dbSLois Curfman McInnes    Not Collective, but Mat object will be parallel if SNES object is
2260c7afd0dbSLois Curfman McInnes 
2261b4fd4287SBarry Smith    Input Parameter:
2262b4fd4287SBarry Smith .  snes - the nonlinear solver context
2263b4fd4287SBarry Smith 
2264b4fd4287SBarry Smith    Output Parameters:
2265c7afd0dbSLois Curfman McInnes +  A - location to stash Jacobian matrix (or PETSC_NULL)
2266b4fd4287SBarry Smith .  B - location to stash preconditioner matrix (or PETSC_NULL)
226770e92668SMatthew Knepley .  func - location to put Jacobian function (or PETSC_NULL)
226870e92668SMatthew Knepley -  ctx - location to stash Jacobian ctx (or PETSC_NULL)
2269fee21e36SBarry Smith 
227036851e7fSLois Curfman McInnes    Level: advanced
227136851e7fSLois Curfman McInnes 
2272b4fd4287SBarry Smith .seealso: SNESSetJacobian(), SNESComputeJacobian()
2273b4fd4287SBarry Smith @*/
22747087cfbeSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
2275b4fd4287SBarry Smith {
22766cab3a1bSJed Brown   PetscErrorCode ierr;
22776cab3a1bSJed Brown   DM             dm;
22786cab3a1bSJed Brown   SNESDM         sdm;
22796cab3a1bSJed Brown 
22803a40ed3dSBarry Smith   PetscFunctionBegin;
22810700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2282b4fd4287SBarry Smith   if (A)    *A    = snes->jacobian;
2283b4fd4287SBarry Smith   if (B)    *B    = snes->jacobian_pre;
22846cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
22856cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
22866cab3a1bSJed Brown   if (func) *func = sdm->computejacobian;
22876cab3a1bSJed Brown   if (ctx)  *ctx  = sdm->jacobianctx;
22883a40ed3dSBarry Smith   PetscFunctionReturn(0);
2289b4fd4287SBarry Smith }
2290b4fd4287SBarry Smith 
22919b94acceSBarry Smith /* ----- Routines to initialize and destroy a nonlinear solver ---- */
22929b94acceSBarry Smith 
22934a2ae208SSatish Balay #undef __FUNCT__
22944a2ae208SSatish Balay #define __FUNCT__ "SNESSetUp"
22959b94acceSBarry Smith /*@
22969b94acceSBarry Smith    SNESSetUp - Sets up the internal data structures for the later use
2297272ac6f2SLois Curfman McInnes    of a nonlinear solver.
22989b94acceSBarry Smith 
2299fee21e36SBarry Smith    Collective on SNES
2300fee21e36SBarry Smith 
2301c7afd0dbSLois Curfman McInnes    Input Parameters:
230270e92668SMatthew Knepley .  snes - the SNES context
2303c7afd0dbSLois Curfman McInnes 
2304272ac6f2SLois Curfman McInnes    Notes:
2305272ac6f2SLois Curfman McInnes    For basic use of the SNES solvers the user need not explicitly call
2306272ac6f2SLois Curfman McInnes    SNESSetUp(), since these actions will automatically occur during
2307272ac6f2SLois Curfman McInnes    the call to SNESSolve().  However, if one wishes to control this
2308272ac6f2SLois Curfman McInnes    phase separately, SNESSetUp() should be called after SNESCreate()
2309272ac6f2SLois Curfman McInnes    and optional routines of the form SNESSetXXX(), but before SNESSolve().
2310272ac6f2SLois Curfman McInnes 
231136851e7fSLois Curfman McInnes    Level: advanced
231236851e7fSLois Curfman McInnes 
23139b94acceSBarry Smith .keywords: SNES, nonlinear, setup
23149b94acceSBarry Smith 
23159b94acceSBarry Smith .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
23169b94acceSBarry Smith @*/
23177087cfbeSBarry Smith PetscErrorCode  SNESSetUp(SNES snes)
23189b94acceSBarry Smith {
2319dfbe8321SBarry Smith   PetscErrorCode ierr;
23206cab3a1bSJed Brown   DM             dm;
23216cab3a1bSJed Brown   SNESDM         sdm;
23223a40ed3dSBarry Smith 
23233a40ed3dSBarry Smith   PetscFunctionBegin;
23240700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
23254dc4c822SBarry Smith   if (snes->setupcalled) PetscFunctionReturn(0);
23269b94acceSBarry Smith 
23277adad957SLisandro Dalcin   if (!((PetscObject)snes)->type_name) {
232885385478SLisandro Dalcin     ierr = SNESSetType(snes,SNESLS);CHKERRQ(ierr);
232985385478SLisandro Dalcin   }
233085385478SLisandro Dalcin 
2331a63bb30eSJed Brown   ierr = SNESGetFunction(snes,&snes->vec_func,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
233217186662SBarry Smith   if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
233358c9b817SLisandro Dalcin   if (snes->vec_rhs  == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
233458c9b817SLisandro Dalcin 
233558c9b817SLisandro Dalcin   if (!snes->vec_sol_update /* && snes->vec_sol */) {
233658c9b817SLisandro Dalcin     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
233758c9b817SLisandro Dalcin     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
233858c9b817SLisandro Dalcin   }
233958c9b817SLisandro Dalcin 
23406cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
23416cab3a1bSJed Brown   ierr = DMSNESSetUpLegacy(dm);CHKERRQ(ierr); /* To be removed when function routines are taken out of the DM package */
23426cab3a1bSJed Brown   ierr = DMSNESGetContext(dm,&sdm);CHKERRQ(ierr);
23436cab3a1bSJed Brown   if (!sdm->computefunction) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction(), DMSNESSetFunction(), DMDASNESSetFunctionLocal(), etc");
23446cab3a1bSJed Brown   if (!snes->vec_func) {
23456cab3a1bSJed Brown     ierr = DMCreateGlobalVector(dm,&snes->vec_func);CHKERRQ(ierr);
2346214df951SJed Brown   }
2347efd51863SBarry Smith 
2348b710008aSBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes, &snes->ksp);CHKERRQ(ierr);}
2349b710008aSBarry Smith 
2350f1c6b773SPeter Brune   if (!snes->linesearch) {ierr = SNESGetSNESLineSearch(snes, &snes->linesearch);}
23519e764e56SPeter Brune 
2352d25893d9SBarry Smith   if (snes->ops->usercompute && !snes->user) {
2353d25893d9SBarry Smith     ierr = (*snes->ops->usercompute)(snes,(void**)&snes->user);CHKERRQ(ierr);
2354d25893d9SBarry Smith   }
2355d25893d9SBarry Smith 
2356410397dcSLisandro Dalcin   if (snes->ops->setup) {
2357410397dcSLisandro Dalcin     ierr = (*snes->ops->setup)(snes);CHKERRQ(ierr);
2358410397dcSLisandro Dalcin   }
235958c9b817SLisandro Dalcin 
23607aaed0d8SBarry Smith   snes->setupcalled = PETSC_TRUE;
23613a40ed3dSBarry Smith   PetscFunctionReturn(0);
23629b94acceSBarry Smith }
23639b94acceSBarry Smith 
23644a2ae208SSatish Balay #undef __FUNCT__
236537596af1SLisandro Dalcin #define __FUNCT__ "SNESReset"
236637596af1SLisandro Dalcin /*@
236737596af1SLisandro Dalcin    SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
236837596af1SLisandro Dalcin 
236937596af1SLisandro Dalcin    Collective on SNES
237037596af1SLisandro Dalcin 
237137596af1SLisandro Dalcin    Input Parameter:
237237596af1SLisandro Dalcin .  snes - iterative context obtained from SNESCreate()
237337596af1SLisandro Dalcin 
2374d25893d9SBarry Smith    Level: intermediate
2375d25893d9SBarry Smith 
2376d25893d9SBarry Smith    Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
237737596af1SLisandro Dalcin 
237837596af1SLisandro Dalcin .keywords: SNES, destroy
237937596af1SLisandro Dalcin 
238037596af1SLisandro Dalcin .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
238137596af1SLisandro Dalcin @*/
238237596af1SLisandro Dalcin PetscErrorCode  SNESReset(SNES snes)
238337596af1SLisandro Dalcin {
238437596af1SLisandro Dalcin   PetscErrorCode ierr;
238537596af1SLisandro Dalcin 
238637596af1SLisandro Dalcin   PetscFunctionBegin;
238737596af1SLisandro Dalcin   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2388d25893d9SBarry Smith   if (snes->ops->userdestroy && snes->user) {
2389d25893d9SBarry Smith     ierr       = (*snes->ops->userdestroy)((void**)&snes->user);CHKERRQ(ierr);
2390d25893d9SBarry Smith     snes->user = PETSC_NULL;
2391d25893d9SBarry Smith   }
23928a23116dSBarry Smith   if (snes->pc) {
23938a23116dSBarry Smith     ierr = SNESReset(snes->pc);CHKERRQ(ierr);
23948a23116dSBarry Smith   }
23958a23116dSBarry Smith 
239637596af1SLisandro Dalcin   if (snes->ops->reset) {
239737596af1SLisandro Dalcin     ierr = (*snes->ops->reset)(snes);CHKERRQ(ierr);
239837596af1SLisandro Dalcin   }
23999e764e56SPeter Brune   if (snes->ksp) {
24009e764e56SPeter Brune     ierr = KSPReset(snes->ksp);CHKERRQ(ierr);
24019e764e56SPeter Brune   }
24029e764e56SPeter Brune 
24039e764e56SPeter Brune   if (snes->linesearch) {
2404f1c6b773SPeter Brune     ierr = SNESLineSearchReset(snes->linesearch);CHKERRQ(ierr);
24059e764e56SPeter Brune   }
24069e764e56SPeter Brune 
24076bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
24086bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
24096bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_sol_update);CHKERRQ(ierr);
24106bf464f9SBarry Smith   ierr = VecDestroy(&snes->vec_func);CHKERRQ(ierr);
24116bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian);CHKERRQ(ierr);
24126bf464f9SBarry Smith   ierr = MatDestroy(&snes->jacobian_pre);CHKERRQ(ierr);
2413c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nwork,&snes->work);CHKERRQ(ierr);
2414c41d97abSJed Brown   ierr = VecDestroyVecs(snes->nvwork,&snes->vwork);CHKERRQ(ierr);
241537596af1SLisandro Dalcin   snes->nwork = snes->nvwork = 0;
241637596af1SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
241737596af1SLisandro Dalcin   PetscFunctionReturn(0);
241837596af1SLisandro Dalcin }
241937596af1SLisandro Dalcin 
242037596af1SLisandro Dalcin #undef __FUNCT__
24214a2ae208SSatish Balay #define __FUNCT__ "SNESDestroy"
242252baeb72SSatish Balay /*@
24239b94acceSBarry Smith    SNESDestroy - Destroys the nonlinear solver context that was created
24249b94acceSBarry Smith    with SNESCreate().
24259b94acceSBarry Smith 
2426c7afd0dbSLois Curfman McInnes    Collective on SNES
2427c7afd0dbSLois Curfman McInnes 
24289b94acceSBarry Smith    Input Parameter:
24299b94acceSBarry Smith .  snes - the SNES context
24309b94acceSBarry Smith 
243136851e7fSLois Curfman McInnes    Level: beginner
243236851e7fSLois Curfman McInnes 
24339b94acceSBarry Smith .keywords: SNES, nonlinear, destroy
24349b94acceSBarry Smith 
243563a78c88SLois Curfman McInnes .seealso: SNESCreate(), SNESSolve()
24369b94acceSBarry Smith @*/
24376bf464f9SBarry Smith PetscErrorCode  SNESDestroy(SNES *snes)
24389b94acceSBarry Smith {
24396849ba73SBarry Smith   PetscErrorCode ierr;
24403a40ed3dSBarry Smith 
24413a40ed3dSBarry Smith   PetscFunctionBegin;
24426bf464f9SBarry Smith   if (!*snes) PetscFunctionReturn(0);
24436bf464f9SBarry Smith   PetscValidHeaderSpecific((*snes),SNES_CLASSID,1);
24446bf464f9SBarry Smith   if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; PetscFunctionReturn(0);}
2445d4bb536fSBarry Smith 
24466bf464f9SBarry Smith   ierr = SNESReset((*snes));CHKERRQ(ierr);
24478a23116dSBarry Smith   ierr = SNESDestroy(&(*snes)->pc);CHKERRQ(ierr);
24486b8b9a38SLisandro Dalcin 
2449be0abb6dSBarry Smith   /* if memory was published with AMS then destroy it */
24506bf464f9SBarry Smith   ierr = PetscObjectDepublish((*snes));CHKERRQ(ierr);
24516bf464f9SBarry Smith   if ((*snes)->ops->destroy) {ierr = (*((*snes))->ops->destroy)((*snes));CHKERRQ(ierr);}
24526d4c513bSLisandro Dalcin 
24536bf464f9SBarry Smith   ierr = DMDestroy(&(*snes)->dm);CHKERRQ(ierr);
24546bf464f9SBarry Smith   ierr = KSPDestroy(&(*snes)->ksp);CHKERRQ(ierr);
2455f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&(*snes)->linesearch);CHKERRQ(ierr);
24566b8b9a38SLisandro Dalcin 
24576bf464f9SBarry Smith   ierr = PetscFree((*snes)->kspconvctx);CHKERRQ(ierr);
24586bf464f9SBarry Smith   if ((*snes)->ops->convergeddestroy) {
24596bf464f9SBarry Smith     ierr = (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);CHKERRQ(ierr);
24606b8b9a38SLisandro Dalcin   }
24616bf464f9SBarry Smith   if ((*snes)->conv_malloc) {
24626bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist);CHKERRQ(ierr);
24636bf464f9SBarry Smith     ierr = PetscFree((*snes)->conv_hist_its);CHKERRQ(ierr);
246458c9b817SLisandro Dalcin   }
24656bf464f9SBarry Smith   ierr = SNESMonitorCancel((*snes));CHKERRQ(ierr);
2466a79aaaedSSatish Balay   ierr = PetscHeaderDestroy(snes);CHKERRQ(ierr);
24673a40ed3dSBarry Smith  PetscFunctionReturn(0);
24689b94acceSBarry Smith }
24699b94acceSBarry Smith 
24709b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */
24719b94acceSBarry Smith 
24724a2ae208SSatish Balay #undef __FUNCT__
2473a8054027SBarry Smith #define __FUNCT__ "SNESSetLagPreconditioner"
2474a8054027SBarry Smith /*@
2475a8054027SBarry Smith    SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
2476a8054027SBarry Smith 
24773f9fe445SBarry Smith    Logically Collective on SNES
2478a8054027SBarry Smith 
2479a8054027SBarry Smith    Input Parameters:
2480a8054027SBarry Smith +  snes - the SNES context
2481a8054027SBarry 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
24823b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2483a8054027SBarry Smith 
2484a8054027SBarry Smith    Options Database Keys:
2485a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2486a8054027SBarry Smith 
2487a8054027SBarry Smith    Notes:
2488a8054027SBarry Smith    The default is 1
2489a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2490a8054027SBarry Smith    If  -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
2491a8054027SBarry Smith 
2492a8054027SBarry Smith    Level: intermediate
2493a8054027SBarry Smith 
2494a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2495a8054027SBarry Smith 
2496e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2497a8054027SBarry Smith 
2498a8054027SBarry Smith @*/
24997087cfbeSBarry Smith PetscErrorCode  SNESSetLagPreconditioner(SNES snes,PetscInt lag)
2500a8054027SBarry Smith {
2501a8054027SBarry Smith   PetscFunctionBegin;
25020700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2503e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2504e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2505c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2506a8054027SBarry Smith   snes->lagpreconditioner = lag;
2507a8054027SBarry Smith   PetscFunctionReturn(0);
2508a8054027SBarry Smith }
2509a8054027SBarry Smith 
2510a8054027SBarry Smith #undef __FUNCT__
2511efd51863SBarry Smith #define __FUNCT__ "SNESSetGridSequence"
2512efd51863SBarry Smith /*@
2513efd51863SBarry Smith    SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
2514efd51863SBarry Smith 
2515efd51863SBarry Smith    Logically Collective on SNES
2516efd51863SBarry Smith 
2517efd51863SBarry Smith    Input Parameters:
2518efd51863SBarry Smith +  snes - the SNES context
2519efd51863SBarry Smith -  steps - the number of refinements to do, defaults to 0
2520efd51863SBarry Smith 
2521efd51863SBarry Smith    Options Database Keys:
2522efd51863SBarry Smith .    -snes_grid_sequence <steps>
2523efd51863SBarry Smith 
2524efd51863SBarry Smith    Level: intermediate
2525efd51863SBarry Smith 
2526c0df2a02SJed Brown    Notes:
2527c0df2a02SJed Brown    Use SNESGetSolution() to extract the fine grid solution after grid sequencing.
2528c0df2a02SJed Brown 
2529efd51863SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2530efd51863SBarry Smith 
2531efd51863SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
2532efd51863SBarry Smith 
2533efd51863SBarry Smith @*/
2534efd51863SBarry Smith PetscErrorCode  SNESSetGridSequence(SNES snes,PetscInt steps)
2535efd51863SBarry Smith {
2536efd51863SBarry Smith   PetscFunctionBegin;
2537efd51863SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2538efd51863SBarry Smith   PetscValidLogicalCollectiveInt(snes,steps,2);
2539efd51863SBarry Smith   snes->gridsequence = steps;
2540efd51863SBarry Smith   PetscFunctionReturn(0);
2541efd51863SBarry Smith }
2542efd51863SBarry Smith 
2543efd51863SBarry Smith #undef __FUNCT__
2544a8054027SBarry Smith #define __FUNCT__ "SNESGetLagPreconditioner"
2545a8054027SBarry Smith /*@
2546a8054027SBarry Smith    SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
2547a8054027SBarry Smith 
25483f9fe445SBarry Smith    Not Collective
2549a8054027SBarry Smith 
2550a8054027SBarry Smith    Input Parameter:
2551a8054027SBarry Smith .  snes - the SNES context
2552a8054027SBarry Smith 
2553a8054027SBarry Smith    Output Parameter:
2554a8054027SBarry 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
25553b4f5425SBarry Smith          the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
2556a8054027SBarry Smith 
2557a8054027SBarry Smith    Options Database Keys:
2558a8054027SBarry Smith .    -snes_lag_preconditioner <lag>
2559a8054027SBarry Smith 
2560a8054027SBarry Smith    Notes:
2561a8054027SBarry Smith    The default is 1
2562a8054027SBarry Smith    The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2563a8054027SBarry Smith 
2564a8054027SBarry Smith    Level: intermediate
2565a8054027SBarry Smith 
2566a8054027SBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2567a8054027SBarry Smith 
2568a8054027SBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
2569a8054027SBarry Smith 
2570a8054027SBarry Smith @*/
25717087cfbeSBarry Smith PetscErrorCode  SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
2572a8054027SBarry Smith {
2573a8054027SBarry Smith   PetscFunctionBegin;
25740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2575a8054027SBarry Smith   *lag = snes->lagpreconditioner;
2576a8054027SBarry Smith   PetscFunctionReturn(0);
2577a8054027SBarry Smith }
2578a8054027SBarry Smith 
2579a8054027SBarry Smith #undef __FUNCT__
2580e35cf81dSBarry Smith #define __FUNCT__ "SNESSetLagJacobian"
2581e35cf81dSBarry Smith /*@
2582e35cf81dSBarry Smith    SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
2583e35cf81dSBarry Smith      often the preconditioner is rebuilt.
2584e35cf81dSBarry Smith 
25853f9fe445SBarry Smith    Logically Collective on SNES
2586e35cf81dSBarry Smith 
2587e35cf81dSBarry Smith    Input Parameters:
2588e35cf81dSBarry Smith +  snes - the SNES context
2589e35cf81dSBarry 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
2590fe3ffe1eSBarry Smith          the Jacobian is built etc. -2 means rebuild at next chance but then never again
2591e35cf81dSBarry Smith 
2592e35cf81dSBarry Smith    Options Database Keys:
2593e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2594e35cf81dSBarry Smith 
2595e35cf81dSBarry Smith    Notes:
2596e35cf81dSBarry Smith    The default is 1
2597e35cf81dSBarry Smith    The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2598fe3ffe1eSBarry 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
2599fe3ffe1eSBarry Smith    at the next Newton step but never again (unless it is reset to another value)
2600e35cf81dSBarry Smith 
2601e35cf81dSBarry Smith    Level: intermediate
2602e35cf81dSBarry Smith 
2603e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2604e35cf81dSBarry Smith 
2605e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
2606e35cf81dSBarry Smith 
2607e35cf81dSBarry Smith @*/
26087087cfbeSBarry Smith PetscErrorCode  SNESSetLagJacobian(SNES snes,PetscInt lag)
2609e35cf81dSBarry Smith {
2610e35cf81dSBarry Smith   PetscFunctionBegin;
26110700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2612e32f2f54SBarry Smith   if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
2613e32f2f54SBarry Smith   if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
2614c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,lag,2);
2615e35cf81dSBarry Smith   snes->lagjacobian = lag;
2616e35cf81dSBarry Smith   PetscFunctionReturn(0);
2617e35cf81dSBarry Smith }
2618e35cf81dSBarry Smith 
2619e35cf81dSBarry Smith #undef __FUNCT__
2620e35cf81dSBarry Smith #define __FUNCT__ "SNESGetLagJacobian"
2621e35cf81dSBarry Smith /*@
2622e35cf81dSBarry Smith    SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
2623e35cf81dSBarry Smith 
26243f9fe445SBarry Smith    Not Collective
2625e35cf81dSBarry Smith 
2626e35cf81dSBarry Smith    Input Parameter:
2627e35cf81dSBarry Smith .  snes - the SNES context
2628e35cf81dSBarry Smith 
2629e35cf81dSBarry Smith    Output Parameter:
2630e35cf81dSBarry 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
2631e35cf81dSBarry Smith          the Jacobian is built etc.
2632e35cf81dSBarry Smith 
2633e35cf81dSBarry Smith    Options Database Keys:
2634e35cf81dSBarry Smith .    -snes_lag_jacobian <lag>
2635e35cf81dSBarry Smith 
2636e35cf81dSBarry Smith    Notes:
2637e35cf81dSBarry Smith    The default is 1
2638e35cf81dSBarry Smith    The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
2639e35cf81dSBarry Smith 
2640e35cf81dSBarry Smith    Level: intermediate
2641e35cf81dSBarry Smith 
2642e35cf81dSBarry Smith .keywords: SNES, nonlinear, set, convergence, tolerances
2643e35cf81dSBarry Smith 
2644e35cf81dSBarry Smith .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
2645e35cf81dSBarry Smith 
2646e35cf81dSBarry Smith @*/
26477087cfbeSBarry Smith PetscErrorCode  SNESGetLagJacobian(SNES snes,PetscInt *lag)
2648e35cf81dSBarry Smith {
2649e35cf81dSBarry Smith   PetscFunctionBegin;
26500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2651e35cf81dSBarry Smith   *lag = snes->lagjacobian;
2652e35cf81dSBarry Smith   PetscFunctionReturn(0);
2653e35cf81dSBarry Smith }
2654e35cf81dSBarry Smith 
2655e35cf81dSBarry Smith #undef __FUNCT__
26564a2ae208SSatish Balay #define __FUNCT__ "SNESSetTolerances"
26579b94acceSBarry Smith /*@
2658d7a720efSLois Curfman McInnes    SNESSetTolerances - Sets various parameters used in convergence tests.
26599b94acceSBarry Smith 
26603f9fe445SBarry Smith    Logically Collective on SNES
2661c7afd0dbSLois Curfman McInnes 
26629b94acceSBarry Smith    Input Parameters:
2663c7afd0dbSLois Curfman McInnes +  snes - the SNES context
266470441072SBarry Smith .  abstol - absolute convergence tolerance
266533174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
266633174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
266733174efeSLois Curfman McInnes            of the change in the solution between steps
266833174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2669c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2670fee21e36SBarry Smith 
267133174efeSLois Curfman McInnes    Options Database Keys:
267270441072SBarry Smith +    -snes_atol <abstol> - Sets abstol
2673c7afd0dbSLois Curfman McInnes .    -snes_rtol <rtol> - Sets rtol
2674c7afd0dbSLois Curfman McInnes .    -snes_stol <stol> - Sets stol
2675c7afd0dbSLois Curfman McInnes .    -snes_max_it <maxit> - Sets maxit
2676c7afd0dbSLois Curfman McInnes -    -snes_max_funcs <maxf> - Sets maxf
26779b94acceSBarry Smith 
2678d7a720efSLois Curfman McInnes    Notes:
26799b94acceSBarry Smith    The default maximum number of iterations is 50.
26809b94acceSBarry Smith    The default maximum number of function evaluations is 1000.
26819b94acceSBarry Smith 
268236851e7fSLois Curfman McInnes    Level: intermediate
268336851e7fSLois Curfman McInnes 
268433174efeSLois Curfman McInnes .keywords: SNES, nonlinear, set, convergence, tolerances
26859b94acceSBarry Smith 
26862492ecdbSBarry Smith .seealso: SNESSetTrustRegionTolerance()
26879b94acceSBarry Smith @*/
26887087cfbeSBarry Smith PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
26899b94acceSBarry Smith {
26903a40ed3dSBarry Smith   PetscFunctionBegin;
26910700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2692c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,abstol,2);
2693c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol,3);
2694c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,stol,4);
2695c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxit,5);
2696c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,maxf,6);
2697c5eb9154SBarry Smith 
2698ab54825eSJed Brown   if (abstol != PETSC_DEFAULT) {
2699ab54825eSJed Brown     if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
2700ab54825eSJed Brown     snes->abstol = abstol;
2701ab54825eSJed Brown   }
2702ab54825eSJed Brown   if (rtol != PETSC_DEFAULT) {
2703ab54825eSJed 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);
2704ab54825eSJed Brown     snes->rtol = rtol;
2705ab54825eSJed Brown   }
2706ab54825eSJed Brown   if (stol != PETSC_DEFAULT) {
2707ab54825eSJed Brown     if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
2708c60f73f4SPeter Brune     snes->stol = stol;
2709ab54825eSJed Brown   }
2710ab54825eSJed Brown   if (maxit != PETSC_DEFAULT) {
2711ab54825eSJed Brown     if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
2712ab54825eSJed Brown     snes->max_its = maxit;
2713ab54825eSJed Brown   }
2714ab54825eSJed Brown   if (maxf != PETSC_DEFAULT) {
2715ab54825eSJed Brown     if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
2716ab54825eSJed Brown     snes->max_funcs = maxf;
2717ab54825eSJed Brown   }
271888976e71SPeter Brune   snes->tolerancesset = PETSC_TRUE;
27193a40ed3dSBarry Smith   PetscFunctionReturn(0);
27209b94acceSBarry Smith }
27219b94acceSBarry Smith 
27224a2ae208SSatish Balay #undef __FUNCT__
27234a2ae208SSatish Balay #define __FUNCT__ "SNESGetTolerances"
27249b94acceSBarry Smith /*@
272533174efeSLois Curfman McInnes    SNESGetTolerances - Gets various parameters used in convergence tests.
272633174efeSLois Curfman McInnes 
2727c7afd0dbSLois Curfman McInnes    Not Collective
2728c7afd0dbSLois Curfman McInnes 
272933174efeSLois Curfman McInnes    Input Parameters:
2730c7afd0dbSLois Curfman McInnes +  snes - the SNES context
273185385478SLisandro Dalcin .  atol - absolute convergence tolerance
273233174efeSLois Curfman McInnes .  rtol - relative convergence tolerance
273333174efeSLois Curfman McInnes .  stol -  convergence tolerance in terms of the norm
273433174efeSLois Curfman McInnes            of the change in the solution between steps
273533174efeSLois Curfman McInnes .  maxit - maximum number of iterations
2736c7afd0dbSLois Curfman McInnes -  maxf - maximum number of function evaluations
2737fee21e36SBarry Smith 
273833174efeSLois Curfman McInnes    Notes:
273933174efeSLois Curfman McInnes    The user can specify PETSC_NULL for any parameter that is not needed.
274033174efeSLois Curfman McInnes 
274136851e7fSLois Curfman McInnes    Level: intermediate
274236851e7fSLois Curfman McInnes 
274333174efeSLois Curfman McInnes .keywords: SNES, nonlinear, get, convergence, tolerances
274433174efeSLois Curfman McInnes 
274533174efeSLois Curfman McInnes .seealso: SNESSetTolerances()
274633174efeSLois Curfman McInnes @*/
27477087cfbeSBarry Smith PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
274833174efeSLois Curfman McInnes {
27493a40ed3dSBarry Smith   PetscFunctionBegin;
27500700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
275185385478SLisandro Dalcin   if (atol)  *atol  = snes->abstol;
275233174efeSLois Curfman McInnes   if (rtol)  *rtol  = snes->rtol;
2753c60f73f4SPeter Brune   if (stol)  *stol  = snes->stol;
275433174efeSLois Curfman McInnes   if (maxit) *maxit = snes->max_its;
275533174efeSLois Curfman McInnes   if (maxf)  *maxf  = snes->max_funcs;
27563a40ed3dSBarry Smith   PetscFunctionReturn(0);
275733174efeSLois Curfman McInnes }
275833174efeSLois Curfman McInnes 
27594a2ae208SSatish Balay #undef __FUNCT__
27604a2ae208SSatish Balay #define __FUNCT__ "SNESSetTrustRegionTolerance"
276133174efeSLois Curfman McInnes /*@
27629b94acceSBarry Smith    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
27639b94acceSBarry Smith 
27643f9fe445SBarry Smith    Logically Collective on SNES
2765fee21e36SBarry Smith 
2766c7afd0dbSLois Curfman McInnes    Input Parameters:
2767c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2768c7afd0dbSLois Curfman McInnes -  tol - tolerance
2769c7afd0dbSLois Curfman McInnes 
27709b94acceSBarry Smith    Options Database Key:
2771c7afd0dbSLois Curfman McInnes .  -snes_trtol <tol> - Sets tol
27729b94acceSBarry Smith 
277336851e7fSLois Curfman McInnes    Level: intermediate
277436851e7fSLois Curfman McInnes 
27759b94acceSBarry Smith .keywords: SNES, nonlinear, set, trust region, tolerance
27769b94acceSBarry Smith 
27772492ecdbSBarry Smith .seealso: SNESSetTolerances()
27789b94acceSBarry Smith @*/
27797087cfbeSBarry Smith PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
27809b94acceSBarry Smith {
27813a40ed3dSBarry Smith   PetscFunctionBegin;
27820700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2783c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,tol,2);
27849b94acceSBarry Smith   snes->deltatol = tol;
27853a40ed3dSBarry Smith   PetscFunctionReturn(0);
27869b94acceSBarry Smith }
27879b94acceSBarry Smith 
2788df9fa365SBarry Smith /*
2789df9fa365SBarry Smith    Duplicate the lg monitors for SNES from KSP; for some reason with
2790df9fa365SBarry Smith    dynamic libraries things don't work under Sun4 if we just use
2791df9fa365SBarry Smith    macros instead of functions
2792df9fa365SBarry Smith */
27934a2ae208SSatish Balay #undef __FUNCT__
2794a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLG"
27957087cfbeSBarry Smith PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2796ce1608b8SBarry Smith {
2797dfbe8321SBarry Smith   PetscErrorCode ierr;
2798ce1608b8SBarry Smith 
2799ce1608b8SBarry Smith   PetscFunctionBegin;
28000700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
2801a6570f20SBarry Smith   ierr = KSPMonitorLG((KSP)snes,it,norm,ctx);CHKERRQ(ierr);
2802ce1608b8SBarry Smith   PetscFunctionReturn(0);
2803ce1608b8SBarry Smith }
2804ce1608b8SBarry Smith 
28054a2ae208SSatish Balay #undef __FUNCT__
2806a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGCreate"
28077087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2808df9fa365SBarry Smith {
2809dfbe8321SBarry Smith   PetscErrorCode ierr;
2810df9fa365SBarry Smith 
2811df9fa365SBarry Smith   PetscFunctionBegin;
2812a6570f20SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2813df9fa365SBarry Smith   PetscFunctionReturn(0);
2814df9fa365SBarry Smith }
2815df9fa365SBarry Smith 
28164a2ae208SSatish Balay #undef __FUNCT__
2817a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorLGDestroy"
28186bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG *draw)
2819df9fa365SBarry Smith {
2820dfbe8321SBarry Smith   PetscErrorCode ierr;
2821df9fa365SBarry Smith 
2822df9fa365SBarry Smith   PetscFunctionBegin;
2823a6570f20SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2824df9fa365SBarry Smith   PetscFunctionReturn(0);
2825df9fa365SBarry Smith }
2826df9fa365SBarry Smith 
28277087cfbeSBarry Smith extern PetscErrorCode  SNESMonitorRange_Private(SNES,PetscInt,PetscReal*);
2828b271bb04SBarry Smith #undef __FUNCT__
2829b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRange"
28307087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2831b271bb04SBarry Smith {
2832b271bb04SBarry Smith   PetscDrawLG      lg;
2833b271bb04SBarry Smith   PetscErrorCode   ierr;
2834b271bb04SBarry Smith   PetscReal        x,y,per;
2835b271bb04SBarry Smith   PetscViewer      v = (PetscViewer)monctx;
2836b271bb04SBarry Smith   static PetscReal prev; /* should be in the context */
2837b271bb04SBarry Smith   PetscDraw        draw;
2838b271bb04SBarry Smith   PetscFunctionBegin;
2839b271bb04SBarry Smith   if (!monctx) {
2840b271bb04SBarry Smith     MPI_Comm    comm;
2841b271bb04SBarry Smith 
2842b271bb04SBarry Smith     ierr   = PetscObjectGetComm((PetscObject)snes,&comm);CHKERRQ(ierr);
2843b271bb04SBarry Smith     v      = PETSC_VIEWER_DRAW_(comm);
2844b271bb04SBarry Smith   }
2845b271bb04SBarry Smith   ierr   = PetscViewerDrawGetDrawLG(v,0,&lg);CHKERRQ(ierr);
2846b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2847b271bb04SBarry Smith   ierr   = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2848b271bb04SBarry Smith   ierr   = PetscDrawSetTitle(draw,"Residual norm");CHKERRQ(ierr);
2849b271bb04SBarry Smith   x = (PetscReal) n;
2850b271bb04SBarry Smith   if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2851b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2852b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2853b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2854b271bb04SBarry Smith   }
2855b271bb04SBarry Smith 
2856b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,1,&lg);CHKERRQ(ierr);
2857b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2858b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2859b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"% elemts > .2*max elemt");CHKERRQ(ierr);
2860b271bb04SBarry Smith   ierr =  SNESMonitorRange_Private(snes,n,&per);CHKERRQ(ierr);
2861b271bb04SBarry Smith   x = (PetscReal) n;
2862b271bb04SBarry Smith   y = 100.0*per;
2863b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2864b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2865b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2866b271bb04SBarry Smith   }
2867b271bb04SBarry Smith 
2868b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,2,&lg);CHKERRQ(ierr);
2869b271bb04SBarry Smith   if (!n) {prev = rnorm;ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2870b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2871b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");CHKERRQ(ierr);
2872b271bb04SBarry Smith   x = (PetscReal) n;
2873b271bb04SBarry Smith   y = (prev - rnorm)/prev;
2874b271bb04SBarry Smith   ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2875b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2876b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2877b271bb04SBarry Smith   }
2878b271bb04SBarry Smith 
2879b271bb04SBarry Smith   ierr = PetscViewerDrawGetDrawLG(v,3,&lg);CHKERRQ(ierr);
2880b271bb04SBarry Smith   if (!n) {ierr = PetscDrawLGReset(lg);CHKERRQ(ierr);}
2881b271bb04SBarry Smith   ierr = PetscDrawLGGetDraw(lg,&draw);CHKERRQ(ierr);
2882b271bb04SBarry Smith   ierr = PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");CHKERRQ(ierr);
2883b271bb04SBarry Smith   x = (PetscReal) n;
2884b271bb04SBarry Smith   y = (prev - rnorm)/(prev*per);
2885b271bb04SBarry Smith   if (n > 2) { /*skip initial crazy value */
2886b271bb04SBarry Smith     ierr = PetscDrawLGAddPoint(lg,&x,&y);CHKERRQ(ierr);
2887b271bb04SBarry Smith   }
2888b271bb04SBarry Smith   if (n < 20 || !(n % 5)) {
2889b271bb04SBarry Smith     ierr = PetscDrawLGDraw(lg);CHKERRQ(ierr);
2890b271bb04SBarry Smith   }
2891b271bb04SBarry Smith   prev = rnorm;
2892b271bb04SBarry Smith   PetscFunctionReturn(0);
2893b271bb04SBarry Smith }
2894b271bb04SBarry Smith 
2895b271bb04SBarry Smith #undef __FUNCT__
2896b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeCreate"
28977087cfbeSBarry Smith PetscErrorCode  SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2898b271bb04SBarry Smith {
2899b271bb04SBarry Smith   PetscErrorCode ierr;
2900b271bb04SBarry Smith 
2901b271bb04SBarry Smith   PetscFunctionBegin;
2902b271bb04SBarry Smith   ierr = KSPMonitorLGCreate(host,label,x,y,m,n,draw);CHKERRQ(ierr);
2903b271bb04SBarry Smith   PetscFunctionReturn(0);
2904b271bb04SBarry Smith }
2905b271bb04SBarry Smith 
2906b271bb04SBarry Smith #undef __FUNCT__
2907b271bb04SBarry Smith #define __FUNCT__ "SNESMonitorLGRangeDestroy"
29086bf464f9SBarry Smith PetscErrorCode  SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2909b271bb04SBarry Smith {
2910b271bb04SBarry Smith   PetscErrorCode ierr;
2911b271bb04SBarry Smith 
2912b271bb04SBarry Smith   PetscFunctionBegin;
2913b271bb04SBarry Smith   ierr = KSPMonitorLGDestroy(draw);CHKERRQ(ierr);
2914b271bb04SBarry Smith   PetscFunctionReturn(0);
2915b271bb04SBarry Smith }
2916b271bb04SBarry Smith 
29177a03ce2fSLisandro Dalcin #undef __FUNCT__
29187a03ce2fSLisandro Dalcin #define __FUNCT__ "SNESMonitor"
2919228d79bcSJed Brown /*@
2920228d79bcSJed Brown    SNESMonitor - runs the user provided monitor routines, if they exist
2921228d79bcSJed Brown 
2922228d79bcSJed Brown    Collective on SNES
2923228d79bcSJed Brown 
2924228d79bcSJed Brown    Input Parameters:
2925228d79bcSJed Brown +  snes - nonlinear solver context obtained from SNESCreate()
2926228d79bcSJed Brown .  iter - iteration number
2927228d79bcSJed Brown -  rnorm - relative norm of the residual
2928228d79bcSJed Brown 
2929228d79bcSJed Brown    Notes:
2930228d79bcSJed Brown    This routine is called by the SNES implementations.
2931228d79bcSJed Brown    It does not typically need to be called by the user.
2932228d79bcSJed Brown 
2933228d79bcSJed Brown    Level: developer
2934228d79bcSJed Brown 
2935228d79bcSJed Brown .seealso: SNESMonitorSet()
2936228d79bcSJed Brown @*/
29377a03ce2fSLisandro Dalcin PetscErrorCode  SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
29387a03ce2fSLisandro Dalcin {
29397a03ce2fSLisandro Dalcin   PetscErrorCode ierr;
29407a03ce2fSLisandro Dalcin   PetscInt       i,n = snes->numbermonitors;
29417a03ce2fSLisandro Dalcin 
29427a03ce2fSLisandro Dalcin   PetscFunctionBegin;
29437a03ce2fSLisandro Dalcin   for (i=0; i<n; i++) {
29447a03ce2fSLisandro Dalcin     ierr = (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);CHKERRQ(ierr);
29457a03ce2fSLisandro Dalcin   }
29467a03ce2fSLisandro Dalcin   PetscFunctionReturn(0);
29477a03ce2fSLisandro Dalcin }
29487a03ce2fSLisandro Dalcin 
29499b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */
29509b94acceSBarry Smith 
29514a2ae208SSatish Balay #undef __FUNCT__
2952a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorSet"
29539b94acceSBarry Smith /*@C
2954a6570f20SBarry Smith    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
29559b94acceSBarry Smith    iteration of the nonlinear solver to display the iteration's
29569b94acceSBarry Smith    progress.
29579b94acceSBarry Smith 
29583f9fe445SBarry Smith    Logically Collective on SNES
2959fee21e36SBarry Smith 
2960c7afd0dbSLois Curfman McInnes    Input Parameters:
2961c7afd0dbSLois Curfman McInnes +  snes - the SNES context
2962c7afd0dbSLois Curfman McInnes .  func - monitoring routine
2963b8a78c4aSBarry Smith .  mctx - [optional] user-defined context for private data for the
2964e8105e01SRichard Katz           monitor routine (use PETSC_NULL if no context is desired)
2965b3006f0bSLois Curfman McInnes -  monitordestroy - [optional] routine that frees monitor context
2966b3006f0bSLois Curfman McInnes           (may be PETSC_NULL)
29679b94acceSBarry Smith 
2968c7afd0dbSLois Curfman McInnes    Calling sequence of func:
2969a7cc72afSBarry Smith $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2970c7afd0dbSLois Curfman McInnes 
2971c7afd0dbSLois Curfman McInnes +    snes - the SNES context
2972c7afd0dbSLois Curfman McInnes .    its - iteration number
2973c7afd0dbSLois Curfman McInnes .    norm - 2-norm function value (may be estimated)
297440a0c1c6SLois Curfman McInnes -    mctx - [optional] monitoring context
29759b94acceSBarry Smith 
29769665c990SLois Curfman McInnes    Options Database Keys:
2977a6570f20SBarry Smith +    -snes_monitor        - sets SNESMonitorDefault()
2978a6570f20SBarry Smith .    -snes_monitor_draw    - sets line graph monitor,
2979a6570f20SBarry Smith                             uses SNESMonitorLGCreate()
2980cca6129bSJed Brown -    -snes_monitor_cancel - cancels all monitors that have
2981c7afd0dbSLois Curfman McInnes                             been hardwired into a code by
2982a6570f20SBarry Smith                             calls to SNESMonitorSet(), but
2983c7afd0dbSLois Curfman McInnes                             does not cancel those set via
2984c7afd0dbSLois Curfman McInnes                             the options database.
29859665c990SLois Curfman McInnes 
2986639f9d9dSBarry Smith    Notes:
29876bc08f3fSLois Curfman McInnes    Several different monitoring routines may be set by calling
2988a6570f20SBarry Smith    SNESMonitorSet() multiple times; all will be called in the
29896bc08f3fSLois Curfman McInnes    order in which they were set.
2990639f9d9dSBarry Smith 
2991025f1a04SBarry Smith    Fortran notes: Only a single monitor function can be set for each SNES object
2992025f1a04SBarry Smith 
299336851e7fSLois Curfman McInnes    Level: intermediate
299436851e7fSLois Curfman McInnes 
29959b94acceSBarry Smith .keywords: SNES, nonlinear, set, monitor
29969b94acceSBarry Smith 
2997a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorCancel()
29989b94acceSBarry Smith @*/
2999c2efdce3SBarry Smith PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
30009b94acceSBarry Smith {
3001b90d0a6eSBarry Smith   PetscInt       i;
3002649052a6SBarry Smith   PetscErrorCode ierr;
3003b90d0a6eSBarry Smith 
30043a40ed3dSBarry Smith   PetscFunctionBegin;
30050700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
300617186662SBarry Smith   if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
3007b90d0a6eSBarry Smith   for (i=0; i<snes->numbermonitors;i++) {
3008649052a6SBarry Smith     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
3009649052a6SBarry Smith       if (monitordestroy) {
3010c2efdce3SBarry Smith         ierr = (*monitordestroy)(&mctx);CHKERRQ(ierr);
3011649052a6SBarry Smith       }
3012b90d0a6eSBarry Smith       PetscFunctionReturn(0);
3013b90d0a6eSBarry Smith     }
3014b90d0a6eSBarry Smith   }
3015b90d0a6eSBarry Smith   snes->monitor[snes->numbermonitors]           = monitor;
3016b8a78c4aSBarry Smith   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
3017639f9d9dSBarry Smith   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
30183a40ed3dSBarry Smith   PetscFunctionReturn(0);
30199b94acceSBarry Smith }
30209b94acceSBarry Smith 
30214a2ae208SSatish Balay #undef __FUNCT__
3022a6570f20SBarry Smith #define __FUNCT__ "SNESMonitorCancel"
30235cd90555SBarry Smith /*@C
3024a6570f20SBarry Smith    SNESMonitorCancel - Clears all the monitor functions for a SNES object.
30255cd90555SBarry Smith 
30263f9fe445SBarry Smith    Logically Collective on SNES
3027c7afd0dbSLois Curfman McInnes 
30285cd90555SBarry Smith    Input Parameters:
30295cd90555SBarry Smith .  snes - the SNES context
30305cd90555SBarry Smith 
30311a480d89SAdministrator    Options Database Key:
3032a6570f20SBarry Smith .  -snes_monitor_cancel - cancels all monitors that have been hardwired
3033a6570f20SBarry Smith     into a code by calls to SNESMonitorSet(), but does not cancel those
3034c7afd0dbSLois Curfman McInnes     set via the options database
30355cd90555SBarry Smith 
30365cd90555SBarry Smith    Notes:
30375cd90555SBarry Smith    There is no way to clear one specific monitor from a SNES object.
30385cd90555SBarry Smith 
303936851e7fSLois Curfman McInnes    Level: intermediate
304036851e7fSLois Curfman McInnes 
30415cd90555SBarry Smith .keywords: SNES, nonlinear, set, monitor
30425cd90555SBarry Smith 
3043a6570f20SBarry Smith .seealso: SNESMonitorDefault(), SNESMonitorSet()
30445cd90555SBarry Smith @*/
30457087cfbeSBarry Smith PetscErrorCode  SNESMonitorCancel(SNES snes)
30465cd90555SBarry Smith {
3047d952e501SBarry Smith   PetscErrorCode ierr;
3048d952e501SBarry Smith   PetscInt       i;
3049d952e501SBarry Smith 
30505cd90555SBarry Smith   PetscFunctionBegin;
30510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3052d952e501SBarry Smith   for (i=0; i<snes->numbermonitors; i++) {
3053d952e501SBarry Smith     if (snes->monitordestroy[i]) {
30543c4aec1bSBarry Smith       ierr = (*snes->monitordestroy[i])(&snes->monitorcontext[i]);CHKERRQ(ierr);
3055d952e501SBarry Smith     }
3056d952e501SBarry Smith   }
30575cd90555SBarry Smith   snes->numbermonitors = 0;
30585cd90555SBarry Smith   PetscFunctionReturn(0);
30595cd90555SBarry Smith }
30605cd90555SBarry Smith 
30614a2ae208SSatish Balay #undef __FUNCT__
30624a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceTest"
30639b94acceSBarry Smith /*@C
30649b94acceSBarry Smith    SNESSetConvergenceTest - Sets the function that is to be used
30659b94acceSBarry Smith    to test for convergence of the nonlinear iterative solution.
30669b94acceSBarry Smith 
30673f9fe445SBarry Smith    Logically Collective on SNES
3068fee21e36SBarry Smith 
3069c7afd0dbSLois Curfman McInnes    Input Parameters:
3070c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3071c7afd0dbSLois Curfman McInnes .  func - routine to test for convergence
30727f7931b9SBarry Smith .  cctx - [optional] context for private data for the convergence routine  (may be PETSC_NULL)
30737f7931b9SBarry Smith -  destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
30749b94acceSBarry Smith 
3075c7afd0dbSLois Curfman McInnes    Calling sequence of func:
307606ee9f85SBarry Smith $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
3077c7afd0dbSLois Curfman McInnes 
3078c7afd0dbSLois Curfman McInnes +    snes - the SNES context
307906ee9f85SBarry Smith .    it - current iteration (0 is the first and is before any Newton step)
3080c7afd0dbSLois Curfman McInnes .    cctx - [optional] convergence context
3081184914b5SBarry Smith .    reason - reason for convergence/divergence
3082c7afd0dbSLois Curfman McInnes .    xnorm - 2-norm of current iterate
30834b27c08aSLois Curfman McInnes .    gnorm - 2-norm of current step
30844b27c08aSLois Curfman McInnes -    f - 2-norm of function
30859b94acceSBarry Smith 
308636851e7fSLois Curfman McInnes    Level: advanced
308736851e7fSLois Curfman McInnes 
30889b94acceSBarry Smith .keywords: SNES, nonlinear, set, convergence, test
30899b94acceSBarry Smith 
309085385478SLisandro Dalcin .seealso: SNESDefaultConverged(), SNESSkipConverged()
30919b94acceSBarry Smith @*/
30927087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
30939b94acceSBarry Smith {
30947f7931b9SBarry Smith   PetscErrorCode ierr;
30957f7931b9SBarry Smith 
30963a40ed3dSBarry Smith   PetscFunctionBegin;
30970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
309885385478SLisandro Dalcin   if (!func) func = SNESSkipConverged;
30997f7931b9SBarry Smith   if (snes->ops->convergeddestroy) {
31007f7931b9SBarry Smith     ierr = (*snes->ops->convergeddestroy)(snes->cnvP);CHKERRQ(ierr);
31017f7931b9SBarry Smith   }
310285385478SLisandro Dalcin   snes->ops->converged        = func;
31037f7931b9SBarry Smith   snes->ops->convergeddestroy = destroy;
310485385478SLisandro Dalcin   snes->cnvP                  = cctx;
31053a40ed3dSBarry Smith   PetscFunctionReturn(0);
31069b94acceSBarry Smith }
31079b94acceSBarry Smith 
31084a2ae208SSatish Balay #undef __FUNCT__
31094a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergedReason"
311052baeb72SSatish Balay /*@
3111184914b5SBarry Smith    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
3112184914b5SBarry Smith 
3113184914b5SBarry Smith    Not Collective
3114184914b5SBarry Smith 
3115184914b5SBarry Smith    Input Parameter:
3116184914b5SBarry Smith .  snes - the SNES context
3117184914b5SBarry Smith 
3118184914b5SBarry Smith    Output Parameter:
31194d0a8057SBarry Smith .  reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
3120184914b5SBarry Smith             manual pages for the individual convergence tests for complete lists
3121184914b5SBarry Smith 
3122184914b5SBarry Smith    Level: intermediate
3123184914b5SBarry Smith 
3124184914b5SBarry Smith    Notes: Can only be called after the call the SNESSolve() is complete.
3125184914b5SBarry Smith 
3126184914b5SBarry Smith .keywords: SNES, nonlinear, set, convergence, test
3127184914b5SBarry Smith 
312885385478SLisandro Dalcin .seealso: SNESSetConvergenceTest(), SNESConvergedReason
3129184914b5SBarry Smith @*/
31307087cfbeSBarry Smith PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
3131184914b5SBarry Smith {
3132184914b5SBarry Smith   PetscFunctionBegin;
31330700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31344482741eSBarry Smith   PetscValidPointer(reason,2);
3135184914b5SBarry Smith   *reason = snes->reason;
3136184914b5SBarry Smith   PetscFunctionReturn(0);
3137184914b5SBarry Smith }
3138184914b5SBarry Smith 
31394a2ae208SSatish Balay #undef __FUNCT__
31404a2ae208SSatish Balay #define __FUNCT__ "SNESSetConvergenceHistory"
3141c9005455SLois Curfman McInnes /*@
3142c9005455SLois Curfman McInnes    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
3143c9005455SLois Curfman McInnes 
31443f9fe445SBarry Smith    Logically Collective on SNES
3145fee21e36SBarry Smith 
3146c7afd0dbSLois Curfman McInnes    Input Parameters:
3147c7afd0dbSLois Curfman McInnes +  snes - iterative context obtained from SNESCreate()
31488c7482ecSBarry Smith .  a   - array to hold history, this array will contain the function norms computed at each step
3149cd5578b5SBarry Smith .  its - integer array holds the number of linear iterations for each solve.
3150758f92a0SBarry Smith .  na  - size of a and its
315164731454SLois Curfman McInnes -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
3152758f92a0SBarry Smith            else it continues storing new values for new nonlinear solves after the old ones
3153c7afd0dbSLois Curfman McInnes 
3154308dcc3eSBarry Smith    Notes:
3155308dcc3eSBarry Smith    If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
3156308dcc3eSBarry Smith    default array of length 10000 is allocated.
3157308dcc3eSBarry Smith 
3158c9005455SLois Curfman McInnes    This routine is useful, e.g., when running a code for purposes
3159c9005455SLois Curfman McInnes    of accurate performance monitoring, when no I/O should be done
3160c9005455SLois Curfman McInnes    during the section of code that is being timed.
3161c9005455SLois Curfman McInnes 
316236851e7fSLois Curfman McInnes    Level: intermediate
316336851e7fSLois Curfman McInnes 
3164c9005455SLois Curfman McInnes .keywords: SNES, set, convergence, history
3165758f92a0SBarry Smith 
316608405cd6SLois Curfman McInnes .seealso: SNESGetConvergenceHistory()
3167758f92a0SBarry Smith 
3168c9005455SLois Curfman McInnes @*/
31697087cfbeSBarry Smith PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool  reset)
3170c9005455SLois Curfman McInnes {
3171308dcc3eSBarry Smith   PetscErrorCode ierr;
3172308dcc3eSBarry Smith 
31733a40ed3dSBarry Smith   PetscFunctionBegin;
31740700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
31754482741eSBarry Smith   if (na)  PetscValidScalarPointer(a,2);
3176a562a398SLisandro Dalcin   if (its) PetscValidIntPointer(its,3);
3177308dcc3eSBarry Smith   if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
3178308dcc3eSBarry Smith     if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
3179308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscReal),&a);CHKERRQ(ierr);
3180308dcc3eSBarry Smith     ierr = PetscMalloc(na*sizeof(PetscInt),&its);CHKERRQ(ierr);
3181308dcc3eSBarry Smith     snes->conv_malloc   = PETSC_TRUE;
3182308dcc3eSBarry Smith   }
3183c9005455SLois Curfman McInnes   snes->conv_hist       = a;
3184758f92a0SBarry Smith   snes->conv_hist_its   = its;
3185758f92a0SBarry Smith   snes->conv_hist_max   = na;
3186a12bc48fSLisandro Dalcin   snes->conv_hist_len   = 0;
3187758f92a0SBarry Smith   snes->conv_hist_reset = reset;
3188758f92a0SBarry Smith   PetscFunctionReturn(0);
3189758f92a0SBarry Smith }
3190758f92a0SBarry Smith 
3191308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
3192c6db04a5SJed Brown #include <engine.h>   /* MATLAB include file */
3193c6db04a5SJed Brown #include <mex.h>      /* MATLAB include file */
3194308dcc3eSBarry Smith EXTERN_C_BEGIN
3195308dcc3eSBarry Smith #undef __FUNCT__
3196308dcc3eSBarry Smith #define __FUNCT__ "SNESGetConvergenceHistoryMatlab"
3197308dcc3eSBarry Smith mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
3198308dcc3eSBarry Smith {
3199308dcc3eSBarry Smith   mxArray        *mat;
3200308dcc3eSBarry Smith   PetscInt       i;
3201308dcc3eSBarry Smith   PetscReal      *ar;
3202308dcc3eSBarry Smith 
3203308dcc3eSBarry Smith   PetscFunctionBegin;
3204308dcc3eSBarry Smith   mat  = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
3205308dcc3eSBarry Smith   ar   = (PetscReal*) mxGetData(mat);
3206308dcc3eSBarry Smith   for (i=0; i<snes->conv_hist_len; i++) {
3207308dcc3eSBarry Smith     ar[i] = snes->conv_hist[i];
3208308dcc3eSBarry Smith   }
3209308dcc3eSBarry Smith   PetscFunctionReturn(mat);
3210308dcc3eSBarry Smith }
3211308dcc3eSBarry Smith EXTERN_C_END
3212308dcc3eSBarry Smith #endif
3213308dcc3eSBarry Smith 
3214308dcc3eSBarry Smith 
32154a2ae208SSatish Balay #undef __FUNCT__
32164a2ae208SSatish Balay #define __FUNCT__ "SNESGetConvergenceHistory"
32170c4c9dddSBarry Smith /*@C
3218758f92a0SBarry Smith    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
3219758f92a0SBarry Smith 
32203f9fe445SBarry Smith    Not Collective
3221758f92a0SBarry Smith 
3222758f92a0SBarry Smith    Input Parameter:
3223758f92a0SBarry Smith .  snes - iterative context obtained from SNESCreate()
3224758f92a0SBarry Smith 
3225758f92a0SBarry Smith    Output Parameters:
3226758f92a0SBarry Smith .  a   - array to hold history
3227758f92a0SBarry Smith .  its - integer array holds the number of linear iterations (or
3228758f92a0SBarry Smith          negative if not converged) for each solve.
3229758f92a0SBarry Smith -  na  - size of a and its
3230758f92a0SBarry Smith 
3231758f92a0SBarry Smith    Notes:
3232758f92a0SBarry Smith     The calling sequence for this routine in Fortran is
3233758f92a0SBarry Smith $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
3234758f92a0SBarry Smith 
3235758f92a0SBarry Smith    This routine is useful, e.g., when running a code for purposes
3236758f92a0SBarry Smith    of accurate performance monitoring, when no I/O should be done
3237758f92a0SBarry Smith    during the section of code that is being timed.
3238758f92a0SBarry Smith 
3239758f92a0SBarry Smith    Level: intermediate
3240758f92a0SBarry Smith 
3241758f92a0SBarry Smith .keywords: SNES, get, convergence, history
3242758f92a0SBarry Smith 
3243758f92a0SBarry Smith .seealso: SNESSetConvergencHistory()
3244758f92a0SBarry Smith 
3245758f92a0SBarry Smith @*/
32467087cfbeSBarry Smith PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
3247758f92a0SBarry Smith {
3248758f92a0SBarry Smith   PetscFunctionBegin;
32490700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3250758f92a0SBarry Smith   if (a)   *a   = snes->conv_hist;
3251758f92a0SBarry Smith   if (its) *its = snes->conv_hist_its;
3252758f92a0SBarry Smith   if (na)  *na  = snes->conv_hist_len;
32533a40ed3dSBarry Smith   PetscFunctionReturn(0);
3254c9005455SLois Curfman McInnes }
3255c9005455SLois Curfman McInnes 
3256e74ef692SMatthew Knepley #undef __FUNCT__
3257e74ef692SMatthew Knepley #define __FUNCT__ "SNESSetUpdate"
3258ac226902SBarry Smith /*@C
325976b2cf59SMatthew Knepley   SNESSetUpdate - Sets the general-purpose update function called
3260eec8f646SJed Brown   at the beginning of every iteration of the nonlinear solve. Specifically
32617e4bb74cSBarry Smith   it is called just before the Jacobian is "evaluated".
326276b2cf59SMatthew Knepley 
32633f9fe445SBarry Smith   Logically Collective on SNES
326476b2cf59SMatthew Knepley 
326576b2cf59SMatthew Knepley   Input Parameters:
326676b2cf59SMatthew Knepley . snes - The nonlinear solver context
326776b2cf59SMatthew Knepley . func - The function
326876b2cf59SMatthew Knepley 
326976b2cf59SMatthew Knepley   Calling sequence of func:
3270b5d30489SBarry Smith . func (SNES snes, PetscInt step);
327176b2cf59SMatthew Knepley 
327276b2cf59SMatthew Knepley . step - The current step of the iteration
327376b2cf59SMatthew Knepley 
3274fe97e370SBarry Smith   Level: advanced
3275fe97e370SBarry Smith 
3276fe97e370SBarry 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()
3277fe97e370SBarry Smith         This is not used by most users.
327876b2cf59SMatthew Knepley 
327976b2cf59SMatthew Knepley .keywords: SNES, update
3280b5d30489SBarry Smith 
328185385478SLisandro Dalcin .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
328276b2cf59SMatthew Knepley @*/
32837087cfbeSBarry Smith PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
328476b2cf59SMatthew Knepley {
328576b2cf59SMatthew Knepley   PetscFunctionBegin;
32860700a824SBarry Smith   PetscValidHeaderSpecific(snes, SNES_CLASSID,1);
3287e7788613SBarry Smith   snes->ops->update = func;
328876b2cf59SMatthew Knepley   PetscFunctionReturn(0);
328976b2cf59SMatthew Knepley }
329076b2cf59SMatthew Knepley 
3291e74ef692SMatthew Knepley #undef __FUNCT__
3292e74ef692SMatthew Knepley #define __FUNCT__ "SNESDefaultUpdate"
329376b2cf59SMatthew Knepley /*@
329476b2cf59SMatthew Knepley   SNESDefaultUpdate - The default update function which does nothing.
329576b2cf59SMatthew Knepley 
329676b2cf59SMatthew Knepley   Not collective
329776b2cf59SMatthew Knepley 
329876b2cf59SMatthew Knepley   Input Parameters:
329976b2cf59SMatthew Knepley . snes - The nonlinear solver context
330076b2cf59SMatthew Knepley . step - The current step of the iteration
330176b2cf59SMatthew Knepley 
3302205452f4SMatthew Knepley   Level: intermediate
3303205452f4SMatthew Knepley 
330476b2cf59SMatthew Knepley .keywords: SNES, update
3305a6570f20SBarry Smith .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
330676b2cf59SMatthew Knepley @*/
33077087cfbeSBarry Smith PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
330876b2cf59SMatthew Knepley {
330976b2cf59SMatthew Knepley   PetscFunctionBegin;
331076b2cf59SMatthew Knepley   PetscFunctionReturn(0);
331176b2cf59SMatthew Knepley }
331276b2cf59SMatthew Knepley 
33134a2ae208SSatish Balay #undef __FUNCT__
33144a2ae208SSatish Balay #define __FUNCT__ "SNESScaleStep_Private"
33159b94acceSBarry Smith /*
33169b94acceSBarry Smith    SNESScaleStep_Private - Scales a step so that its length is less than the
33179b94acceSBarry Smith    positive parameter delta.
33189b94acceSBarry Smith 
33199b94acceSBarry Smith     Input Parameters:
3320c7afd0dbSLois Curfman McInnes +   snes - the SNES context
33219b94acceSBarry Smith .   y - approximate solution of linear system
33229b94acceSBarry Smith .   fnorm - 2-norm of current function
3323c7afd0dbSLois Curfman McInnes -   delta - trust region size
33249b94acceSBarry Smith 
33259b94acceSBarry Smith     Output Parameters:
3326c7afd0dbSLois Curfman McInnes +   gpnorm - predicted function norm at the new point, assuming local
33279b94acceSBarry Smith     linearization.  The value is zero if the step lies within the trust
33289b94acceSBarry Smith     region, and exceeds zero otherwise.
3329c7afd0dbSLois Curfman McInnes -   ynorm - 2-norm of the step
33309b94acceSBarry Smith 
33319b94acceSBarry Smith     Note:
33324b27c08aSLois Curfman McInnes     For non-trust region methods such as SNESLS, the parameter delta
33339b94acceSBarry Smith     is set to be the maximum allowable step size.
33349b94acceSBarry Smith 
33359b94acceSBarry Smith .keywords: SNES, nonlinear, scale, step
33369b94acceSBarry Smith */
3337dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
33389b94acceSBarry Smith {
3339064f8208SBarry Smith   PetscReal      nrm;
3340ea709b57SSatish Balay   PetscScalar    cnorm;
3341dfbe8321SBarry Smith   PetscErrorCode ierr;
33423a40ed3dSBarry Smith 
33433a40ed3dSBarry Smith   PetscFunctionBegin;
33440700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
33450700a824SBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,2);
3346c9780b6fSBarry Smith   PetscCheckSameComm(snes,1,y,2);
3347184914b5SBarry Smith 
3348064f8208SBarry Smith   ierr = VecNorm(y,NORM_2,&nrm);CHKERRQ(ierr);
3349064f8208SBarry Smith   if (nrm > *delta) {
3350064f8208SBarry Smith      nrm = *delta/nrm;
3351064f8208SBarry Smith      *gpnorm = (1.0 - nrm)*(*fnorm);
3352064f8208SBarry Smith      cnorm = nrm;
33532dcb1b2aSMatthew Knepley      ierr = VecScale(y,cnorm);CHKERRQ(ierr);
33549b94acceSBarry Smith      *ynorm = *delta;
33559b94acceSBarry Smith   } else {
33569b94acceSBarry Smith      *gpnorm = 0.0;
3357064f8208SBarry Smith      *ynorm = nrm;
33589b94acceSBarry Smith   }
33593a40ed3dSBarry Smith   PetscFunctionReturn(0);
33609b94acceSBarry Smith }
33619b94acceSBarry Smith 
33624a2ae208SSatish Balay #undef __FUNCT__
33634a2ae208SSatish Balay #define __FUNCT__ "SNESSolve"
33646ce558aeSBarry Smith /*@C
3365f69a0ea3SMatthew Knepley    SNESSolve - Solves a nonlinear system F(x) = b.
3366f69a0ea3SMatthew Knepley    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
33679b94acceSBarry Smith 
3368c7afd0dbSLois Curfman McInnes    Collective on SNES
3369c7afd0dbSLois Curfman McInnes 
3370b2002411SLois Curfman McInnes    Input Parameters:
3371c7afd0dbSLois Curfman McInnes +  snes - the SNES context
33723cebf274SJed Brown .  b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
337385385478SLisandro Dalcin -  x - the solution vector.
33749b94acceSBarry Smith 
3375b2002411SLois Curfman McInnes    Notes:
33768ddd3da0SLois Curfman McInnes    The user should initialize the vector,x, with the initial guess
33778ddd3da0SLois Curfman McInnes    for the nonlinear solve prior to calling SNESSolve.  In particular,
33788ddd3da0SLois Curfman McInnes    to employ an initial guess of zero, the user should explicitly set
33798ddd3da0SLois Curfman McInnes    this vector to zero by calling VecSet().
33808ddd3da0SLois Curfman McInnes 
338136851e7fSLois Curfman McInnes    Level: beginner
338236851e7fSLois Curfman McInnes 
33839b94acceSBarry Smith .keywords: SNES, nonlinear, solve
33849b94acceSBarry Smith 
3385c0df2a02SJed Brown .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetGridSequence(), SNESGetSolution()
33869b94acceSBarry Smith @*/
33877087cfbeSBarry Smith PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
33889b94acceSBarry Smith {
3389dfbe8321SBarry Smith   PetscErrorCode ierr;
3390ace3abfcSBarry Smith   PetscBool      flg;
3391eabae89aSBarry Smith   char           filename[PETSC_MAX_PATH_LEN];
3392eabae89aSBarry Smith   PetscViewer    viewer;
3393efd51863SBarry Smith   PetscInt       grid;
3394a69afd8bSBarry Smith   Vec            xcreated = PETSC_NULL;
3395caa4e7f2SJed Brown   DM             dm;
3396052efed2SBarry Smith 
33973a40ed3dSBarry Smith   PetscFunctionBegin;
33980700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3399a69afd8bSBarry Smith   if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3);
3400a69afd8bSBarry Smith   if (x) PetscCheckSameComm(snes,1,x,3);
34010700a824SBarry Smith   if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2);
340285385478SLisandro Dalcin   if (b) PetscCheckSameComm(snes,1,b,2);
340385385478SLisandro Dalcin 
3404caa4e7f2SJed Brown   if (!x) {
3405caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3406caa4e7f2SJed Brown     ierr = DMCreateGlobalVector(dm,&xcreated);CHKERRQ(ierr);
3407a69afd8bSBarry Smith     x    = xcreated;
3408a69afd8bSBarry Smith   }
3409a69afd8bSBarry Smith 
3410a8248277SBarry Smith   for (grid=0; grid<snes->gridsequence; grid++) {ierr = PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);}
3411efd51863SBarry Smith   for (grid=0; grid<snes->gridsequence+1; grid++) {
3412efd51863SBarry Smith 
341385385478SLisandro Dalcin     /* set solution vector */
3414efd51863SBarry Smith     if (!grid) {ierr = PetscObjectReference((PetscObject)x);CHKERRQ(ierr);}
34156bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_sol);CHKERRQ(ierr);
341685385478SLisandro Dalcin     snes->vec_sol = x;
3417caa4e7f2SJed Brown     ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
3418caa4e7f2SJed Brown 
3419caa4e7f2SJed Brown     /* set affine vector if provided */
342085385478SLisandro Dalcin     if (b) { ierr = PetscObjectReference((PetscObject)b);CHKERRQ(ierr); }
34216bf464f9SBarry Smith     ierr = VecDestroy(&snes->vec_rhs);CHKERRQ(ierr);
342285385478SLisandro Dalcin     snes->vec_rhs = b;
342385385478SLisandro Dalcin 
342470e92668SMatthew Knepley     ierr = SNESSetUp(snes);CHKERRQ(ierr);
34253f149594SLisandro Dalcin 
34267eee914bSBarry Smith     if (!grid) {
34277eee914bSBarry Smith       if (snes->ops->computeinitialguess) {
3428d25893d9SBarry Smith         ierr = (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);CHKERRQ(ierr);
3429dd568438SSatish Balay       } else if (snes->dm) {
3430dd568438SSatish Balay         PetscBool ig;
3431dd568438SSatish Balay         ierr = DMHasInitialGuess(snes->dm,&ig);CHKERRQ(ierr);
3432dd568438SSatish Balay         if (ig) {
34337eee914bSBarry Smith           ierr = DMComputeInitialGuess(snes->dm,snes->vec_sol);CHKERRQ(ierr);
34347eee914bSBarry Smith         }
3435d25893d9SBarry Smith       }
3436dd568438SSatish Balay     }
3437d25893d9SBarry Smith 
3438abc0a331SBarry Smith     if (snes->conv_hist_reset) snes->conv_hist_len = 0;
343950ffb88aSMatthew Knepley     snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
3440d5e45103SBarry Smith 
34413f149594SLisandro Dalcin     ierr = PetscLogEventBegin(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34424936397dSBarry Smith     ierr = (*snes->ops->solve)(snes);CHKERRQ(ierr);
344385385478SLisandro Dalcin     ierr = PetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(ierr);
34444936397dSBarry Smith     if (snes->domainerror){
34454936397dSBarry Smith       snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
34464936397dSBarry Smith       snes->domainerror = PETSC_FALSE;
34474936397dSBarry Smith     }
344817186662SBarry Smith     if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
34493f149594SLisandro Dalcin 
34507adad957SLisandro Dalcin     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
3451eabae89aSBarry Smith     if (flg && !PetscPreLoadingOn) {
34527adad957SLisandro Dalcin       ierr = PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);CHKERRQ(ierr);
3453eabae89aSBarry Smith       ierr = SNESView(snes,viewer);CHKERRQ(ierr);
34546bf464f9SBarry Smith       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
3455eabae89aSBarry Smith     }
3456eabae89aSBarry Smith 
345790d69ab7SBarry Smith     flg  = PETSC_FALSE;
3458acfcf0e5SJed Brown     ierr = PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);CHKERRQ(ierr);
3459da9b6338SBarry Smith     if (flg && !PetscPreLoadingOn) { ierr = SNESTestLocalMin(snes);CHKERRQ(ierr); }
34605968eb51SBarry Smith     if (snes->printreason) {
3461a8248277SBarry Smith       ierr = PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34625968eb51SBarry Smith       if (snes->reason > 0) {
3463c7e7b494SJed 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);
34645968eb51SBarry Smith       } else {
3465c7e7b494SJed 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);
34665968eb51SBarry Smith       }
3467a8248277SBarry Smith       ierr = PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);CHKERRQ(ierr);
34685968eb51SBarry Smith     }
34695968eb51SBarry Smith 
34708501fc72SJed Brown     flg = PETSC_FALSE;
34718501fc72SJed Brown     ierr = PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view_solution_vtk",filename,PETSC_MAX_PATH_LEN,&flg);CHKERRQ(ierr);
34728501fc72SJed Brown     if (flg) {
34738501fc72SJed Brown       PetscViewer viewer;
34748501fc72SJed Brown       ierr = PetscViewerCreate(((PetscObject)snes)->comm,&viewer);CHKERRQ(ierr);
34758501fc72SJed Brown       ierr = PetscViewerSetType(viewer,PETSCVIEWERVTK);CHKERRQ(ierr);
34768501fc72SJed Brown       ierr = PetscViewerFileSetName(viewer,filename);CHKERRQ(ierr);
34778501fc72SJed Brown       ierr = VecView(snes->vec_sol,viewer);CHKERRQ(ierr);
34788501fc72SJed Brown       ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
34798501fc72SJed Brown     }
34808501fc72SJed Brown 
3481e113a28aSBarry Smith     if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
3482efd51863SBarry Smith     if (grid <  snes->gridsequence) {
3483efd51863SBarry Smith       DM  fine;
3484efd51863SBarry Smith       Vec xnew;
3485efd51863SBarry Smith       Mat interp;
3486efd51863SBarry Smith 
3487efd51863SBarry Smith       ierr = DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);CHKERRQ(ierr);
3488c5c77316SJed Brown       if (!fine) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing");
3489e727c939SJed Brown       ierr = DMCreateInterpolation(snes->dm,fine,&interp,PETSC_NULL);CHKERRQ(ierr);
3490efd51863SBarry Smith       ierr = DMCreateGlobalVector(fine,&xnew);CHKERRQ(ierr);
3491efd51863SBarry Smith       ierr = MatInterpolate(interp,x,xnew);CHKERRQ(ierr);
3492efd51863SBarry Smith       ierr = MatDestroy(&interp);CHKERRQ(ierr);
3493efd51863SBarry Smith       x    = xnew;
3494efd51863SBarry Smith 
3495efd51863SBarry Smith       ierr = SNESReset(snes);CHKERRQ(ierr);
3496efd51863SBarry Smith       ierr = SNESSetDM(snes,fine);CHKERRQ(ierr);
3497efd51863SBarry Smith       ierr = DMDestroy(&fine);CHKERRQ(ierr);
3498a8248277SBarry Smith       ierr = PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));CHKERRQ(ierr);
3499efd51863SBarry Smith     }
3500efd51863SBarry Smith   }
3501a69afd8bSBarry Smith   ierr = VecDestroy(&xcreated);CHKERRQ(ierr);
35023a40ed3dSBarry Smith   PetscFunctionReturn(0);
35039b94acceSBarry Smith }
35049b94acceSBarry Smith 
35059b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */
35069b94acceSBarry Smith 
35074a2ae208SSatish Balay #undef __FUNCT__
35084a2ae208SSatish Balay #define __FUNCT__ "SNESSetType"
350982bf6240SBarry Smith /*@C
35104b0e389bSBarry Smith    SNESSetType - Sets the method for the nonlinear solver.
35119b94acceSBarry Smith 
3512fee21e36SBarry Smith    Collective on SNES
3513fee21e36SBarry Smith 
3514c7afd0dbSLois Curfman McInnes    Input Parameters:
3515c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3516454a90a3SBarry Smith -  type - a known method
3517c7afd0dbSLois Curfman McInnes 
3518c7afd0dbSLois Curfman McInnes    Options Database Key:
3519454a90a3SBarry Smith .  -snes_type <type> - Sets the method; use -help for a list
3520c7afd0dbSLois Curfman McInnes    of available methods (for instance, ls or tr)
3521ae12b187SLois Curfman McInnes 
35229b94acceSBarry Smith    Notes:
3523e090d566SSatish Balay    See "petsc/include/petscsnes.h" for available methods (for instance)
35244b27c08aSLois Curfman McInnes +    SNESLS - Newton's method with line search
3525c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35264b27c08aSLois Curfman McInnes .    SNESTR - Newton's method with trust region
3527c7afd0dbSLois Curfman McInnes      (systems of nonlinear equations)
35289b94acceSBarry Smith 
3529ae12b187SLois Curfman McInnes   Normally, it is best to use the SNESSetFromOptions() command and then
3530ae12b187SLois Curfman McInnes   set the SNES solver type from the options database rather than by using
3531ae12b187SLois Curfman McInnes   this routine.  Using the options database provides the user with
3532ae12b187SLois Curfman McInnes   maximum flexibility in evaluating the many nonlinear solvers.
3533ae12b187SLois Curfman McInnes   The SNESSetType() routine is provided for those situations where it
3534ae12b187SLois Curfman McInnes   is necessary to set the nonlinear solver independently of the command
3535ae12b187SLois Curfman McInnes   line or options database.  This might be the case, for example, when
3536ae12b187SLois Curfman McInnes   the choice of solver changes during the execution of the program,
3537ae12b187SLois Curfman McInnes   and the user's application is taking responsibility for choosing the
3538b0a32e0cSBarry Smith   appropriate method.
353936851e7fSLois Curfman McInnes 
354036851e7fSLois Curfman McInnes   Level: intermediate
3541a703fe33SLois Curfman McInnes 
3542454a90a3SBarry Smith .keywords: SNES, set, type
3543435da068SBarry Smith 
3544435da068SBarry Smith .seealso: SNESType, SNESCreate()
3545435da068SBarry Smith 
35469b94acceSBarry Smith @*/
35477087cfbeSBarry Smith PetscErrorCode  SNESSetType(SNES snes,const SNESType type)
35489b94acceSBarry Smith {
3549dfbe8321SBarry Smith   PetscErrorCode ierr,(*r)(SNES);
3550ace3abfcSBarry Smith   PetscBool      match;
35513a40ed3dSBarry Smith 
35523a40ed3dSBarry Smith   PetscFunctionBegin;
35530700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
35544482741eSBarry Smith   PetscValidCharPointer(type,2);
355582bf6240SBarry Smith 
3556251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)snes,type,&match);CHKERRQ(ierr);
35570f5bd95cSBarry Smith   if (match) PetscFunctionReturn(0);
355892ff6ae8SBarry Smith 
35594b91b6eaSBarry Smith   ierr =  PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr);
3560e32f2f54SBarry Smith   if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
356175396ef9SLisandro Dalcin   /* Destroy the previous private SNES context */
3562b5c23020SJed Brown   if (snes->ops->destroy) {
3563b5c23020SJed Brown     ierr = (*(snes)->ops->destroy)(snes);CHKERRQ(ierr);
3564b5c23020SJed Brown     snes->ops->destroy = PETSC_NULL;
3565b5c23020SJed Brown   }
356675396ef9SLisandro Dalcin   /* Reinitialize function pointers in SNESOps structure */
356775396ef9SLisandro Dalcin   snes->ops->setup          = 0;
356875396ef9SLisandro Dalcin   snes->ops->solve          = 0;
356975396ef9SLisandro Dalcin   snes->ops->view           = 0;
357075396ef9SLisandro Dalcin   snes->ops->setfromoptions = 0;
357175396ef9SLisandro Dalcin   snes->ops->destroy        = 0;
357275396ef9SLisandro Dalcin   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
357375396ef9SLisandro Dalcin   snes->setupcalled = PETSC_FALSE;
3574454a90a3SBarry Smith   ierr = PetscObjectChangeTypeName((PetscObject)snes,type);CHKERRQ(ierr);
357503bfa161SLisandro Dalcin   ierr = (*r)(snes);CHKERRQ(ierr);
35769fb22e1aSBarry Smith #if defined(PETSC_HAVE_AMS)
35779fb22e1aSBarry Smith   if (PetscAMSPublishAll) {
35789fb22e1aSBarry Smith     ierr = PetscObjectAMSPublish((PetscObject)snes);CHKERRQ(ierr);
35799fb22e1aSBarry Smith   }
35809fb22e1aSBarry Smith #endif
35813a40ed3dSBarry Smith   PetscFunctionReturn(0);
35829b94acceSBarry Smith }
35839b94acceSBarry Smith 
3584a847f771SSatish Balay 
35859b94acceSBarry Smith /* --------------------------------------------------------------------- */
35864a2ae208SSatish Balay #undef __FUNCT__
35874a2ae208SSatish Balay #define __FUNCT__ "SNESRegisterDestroy"
358852baeb72SSatish Balay /*@
35899b94acceSBarry Smith    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
3590f1af5d2fSBarry Smith    registered by SNESRegisterDynamic().
35919b94acceSBarry Smith 
3592fee21e36SBarry Smith    Not Collective
3593fee21e36SBarry Smith 
359436851e7fSLois Curfman McInnes    Level: advanced
359536851e7fSLois Curfman McInnes 
35969b94acceSBarry Smith .keywords: SNES, nonlinear, register, destroy
35979b94acceSBarry Smith 
35989b94acceSBarry Smith .seealso: SNESRegisterAll(), SNESRegisterAll()
35999b94acceSBarry Smith @*/
36007087cfbeSBarry Smith PetscErrorCode  SNESRegisterDestroy(void)
36019b94acceSBarry Smith {
3602dfbe8321SBarry Smith   PetscErrorCode ierr;
360382bf6240SBarry Smith 
36043a40ed3dSBarry Smith   PetscFunctionBegin;
36051441b1d3SBarry Smith   ierr = PetscFListDestroy(&SNESList);CHKERRQ(ierr);
36064c49b128SBarry Smith   SNESRegisterAllCalled = PETSC_FALSE;
36073a40ed3dSBarry Smith   PetscFunctionReturn(0);
36089b94acceSBarry Smith }
36099b94acceSBarry Smith 
36104a2ae208SSatish Balay #undef __FUNCT__
36114a2ae208SSatish Balay #define __FUNCT__ "SNESGetType"
36129b94acceSBarry Smith /*@C
36139a28b0a6SLois Curfman McInnes    SNESGetType - Gets the SNES method type and name (as a string).
36149b94acceSBarry Smith 
3615c7afd0dbSLois Curfman McInnes    Not Collective
3616c7afd0dbSLois Curfman McInnes 
36179b94acceSBarry Smith    Input Parameter:
36184b0e389bSBarry Smith .  snes - nonlinear solver context
36199b94acceSBarry Smith 
36209b94acceSBarry Smith    Output Parameter:
36213a7fca6bSBarry Smith .  type - SNES method (a character string)
36229b94acceSBarry Smith 
362336851e7fSLois Curfman McInnes    Level: intermediate
362436851e7fSLois Curfman McInnes 
3625454a90a3SBarry Smith .keywords: SNES, nonlinear, get, type, name
36269b94acceSBarry Smith @*/
36277087cfbeSBarry Smith PetscErrorCode  SNESGetType(SNES snes,const SNESType *type)
36289b94acceSBarry Smith {
36293a40ed3dSBarry Smith   PetscFunctionBegin;
36300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36314482741eSBarry Smith   PetscValidPointer(type,2);
36327adad957SLisandro Dalcin   *type = ((PetscObject)snes)->type_name;
36333a40ed3dSBarry Smith   PetscFunctionReturn(0);
36349b94acceSBarry Smith }
36359b94acceSBarry Smith 
36364a2ae208SSatish Balay #undef __FUNCT__
36374a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolution"
363852baeb72SSatish Balay /*@
36399b94acceSBarry Smith    SNESGetSolution - Returns the vector where the approximate solution is
3640c0df2a02SJed Brown    stored. This is the fine grid solution when using SNESSetGridSequence().
36419b94acceSBarry Smith 
3642c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3643c7afd0dbSLois Curfman McInnes 
36449b94acceSBarry Smith    Input Parameter:
36459b94acceSBarry Smith .  snes - the SNES context
36469b94acceSBarry Smith 
36479b94acceSBarry Smith    Output Parameter:
36489b94acceSBarry Smith .  x - the solution
36499b94acceSBarry Smith 
365070e92668SMatthew Knepley    Level: intermediate
365136851e7fSLois Curfman McInnes 
36529b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution
36539b94acceSBarry Smith 
365485385478SLisandro Dalcin .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
36559b94acceSBarry Smith @*/
36567087cfbeSBarry Smith PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
36579b94acceSBarry Smith {
36583a40ed3dSBarry Smith   PetscFunctionBegin;
36590700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36604482741eSBarry Smith   PetscValidPointer(x,2);
366185385478SLisandro Dalcin   *x = snes->vec_sol;
366270e92668SMatthew Knepley   PetscFunctionReturn(0);
366370e92668SMatthew Knepley }
366470e92668SMatthew Knepley 
366570e92668SMatthew Knepley #undef __FUNCT__
36664a2ae208SSatish Balay #define __FUNCT__ "SNESGetSolutionUpdate"
366752baeb72SSatish Balay /*@
36689b94acceSBarry Smith    SNESGetSolutionUpdate - Returns the vector where the solution update is
36699b94acceSBarry Smith    stored.
36709b94acceSBarry Smith 
3671c7afd0dbSLois Curfman McInnes    Not Collective, but Vec is parallel if SNES is parallel
3672c7afd0dbSLois Curfman McInnes 
36739b94acceSBarry Smith    Input Parameter:
36749b94acceSBarry Smith .  snes - the SNES context
36759b94acceSBarry Smith 
36769b94acceSBarry Smith    Output Parameter:
36779b94acceSBarry Smith .  x - the solution update
36789b94acceSBarry Smith 
367936851e7fSLois Curfman McInnes    Level: advanced
368036851e7fSLois Curfman McInnes 
36819b94acceSBarry Smith .keywords: SNES, nonlinear, get, solution, update
36829b94acceSBarry Smith 
368385385478SLisandro Dalcin .seealso: SNESGetSolution(), SNESGetFunction()
36849b94acceSBarry Smith @*/
36857087cfbeSBarry Smith PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
36869b94acceSBarry Smith {
36873a40ed3dSBarry Smith   PetscFunctionBegin;
36880700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
36894482741eSBarry Smith   PetscValidPointer(x,2);
369085385478SLisandro Dalcin   *x = snes->vec_sol_update;
36913a40ed3dSBarry Smith   PetscFunctionReturn(0);
36929b94acceSBarry Smith }
36939b94acceSBarry Smith 
36944a2ae208SSatish Balay #undef __FUNCT__
36954a2ae208SSatish Balay #define __FUNCT__ "SNESGetFunction"
36969b94acceSBarry Smith /*@C
36973638b69dSLois Curfman McInnes    SNESGetFunction - Returns the vector where the function is stored.
36989b94acceSBarry Smith 
3699a63bb30eSJed Brown    Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet.
3700c7afd0dbSLois Curfman McInnes 
37019b94acceSBarry Smith    Input Parameter:
37029b94acceSBarry Smith .  snes - the SNES context
37039b94acceSBarry Smith 
37049b94acceSBarry Smith    Output Parameter:
37057bf4e008SBarry Smith +  r - the function (or PETSC_NULL)
370670e92668SMatthew Knepley .  func - the function (or PETSC_NULL)
370770e92668SMatthew Knepley -  ctx - the function context (or PETSC_NULL)
37089b94acceSBarry Smith 
370936851e7fSLois Curfman McInnes    Level: advanced
371036851e7fSLois Curfman McInnes 
3711a86d99e1SLois Curfman McInnes .keywords: SNES, nonlinear, get, function
37129b94acceSBarry Smith 
37134b27c08aSLois Curfman McInnes .seealso: SNESSetFunction(), SNESGetSolution()
37149b94acceSBarry Smith @*/
37157087cfbeSBarry Smith PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
37169b94acceSBarry Smith {
3717a63bb30eSJed Brown   PetscErrorCode ierr;
37186cab3a1bSJed Brown   DM             dm;
3719a63bb30eSJed Brown 
37203a40ed3dSBarry Smith   PetscFunctionBegin;
37210700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3722a63bb30eSJed Brown   if (r) {
3723a63bb30eSJed Brown     if (!snes->vec_func) {
3724a63bb30eSJed Brown       if (snes->vec_rhs) {
3725a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_rhs,&snes->vec_func);CHKERRQ(ierr);
3726a63bb30eSJed Brown       } else if (snes->vec_sol) {
3727a63bb30eSJed Brown         ierr = VecDuplicate(snes->vec_sol,&snes->vec_func);CHKERRQ(ierr);
3728a63bb30eSJed Brown       } else if (snes->dm) {
3729a63bb30eSJed Brown         ierr = DMCreateGlobalVector(snes->dm,&snes->vec_func);CHKERRQ(ierr);
3730a63bb30eSJed Brown       }
3731a63bb30eSJed Brown     }
3732a63bb30eSJed Brown     *r = snes->vec_func;
3733a63bb30eSJed Brown   }
37346cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37356cab3a1bSJed Brown   ierr = DMSNESGetFunction(dm,func,ctx);CHKERRQ(ierr);
37363a40ed3dSBarry Smith   PetscFunctionReturn(0);
37379b94acceSBarry Smith }
37389b94acceSBarry Smith 
3739c79ef259SPeter Brune /*@C
3740c79ef259SPeter Brune    SNESGetGS - Returns the GS function and context.
3741c79ef259SPeter Brune 
3742c79ef259SPeter Brune    Input Parameter:
3743c79ef259SPeter Brune .  snes - the SNES context
3744c79ef259SPeter Brune 
3745c79ef259SPeter Brune    Output Parameter:
3746c79ef259SPeter Brune +  gsfunc - the function (or PETSC_NULL)
3747c79ef259SPeter Brune -  ctx    - the function context (or PETSC_NULL)
3748c79ef259SPeter Brune 
3749c79ef259SPeter Brune    Level: advanced
3750c79ef259SPeter Brune 
3751c79ef259SPeter Brune .keywords: SNES, nonlinear, get, function
3752c79ef259SPeter Brune 
3753c79ef259SPeter Brune .seealso: SNESSetGS(), SNESGetFunction()
3754c79ef259SPeter Brune @*/
3755c79ef259SPeter Brune 
37564a2ae208SSatish Balay #undef __FUNCT__
3757646217ecSPeter Brune #define __FUNCT__ "SNESGetGS"
3758646217ecSPeter Brune PetscErrorCode SNESGetGS (SNES snes, PetscErrorCode(**func)(SNES, Vec, Vec, void*), void ** ctx)
3759646217ecSPeter Brune {
37606cab3a1bSJed Brown   PetscErrorCode ierr;
37616cab3a1bSJed Brown   DM             dm;
37626cab3a1bSJed Brown 
3763646217ecSPeter Brune   PetscFunctionBegin;
3764646217ecSPeter Brune   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
37656cab3a1bSJed Brown   ierr = SNESGetDM(snes,&dm);CHKERRQ(ierr);
37666cab3a1bSJed Brown   ierr = DMSNESGetGS(dm,func,ctx);CHKERRQ(ierr);
3767646217ecSPeter Brune   PetscFunctionReturn(0);
3768646217ecSPeter Brune }
3769646217ecSPeter Brune 
37704a2ae208SSatish Balay #undef __FUNCT__
37714a2ae208SSatish Balay #define __FUNCT__ "SNESSetOptionsPrefix"
37723c7409f5SSatish Balay /*@C
37733c7409f5SSatish Balay    SNESSetOptionsPrefix - Sets the prefix used for searching for all
3774d850072dSLois Curfman McInnes    SNES options in the database.
37753c7409f5SSatish Balay 
37763f9fe445SBarry Smith    Logically Collective on SNES
3777fee21e36SBarry Smith 
3778c7afd0dbSLois Curfman McInnes    Input Parameter:
3779c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3780c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3781c7afd0dbSLois Curfman McInnes 
3782d850072dSLois Curfman McInnes    Notes:
3783a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3784c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3785d850072dSLois Curfman McInnes 
378636851e7fSLois Curfman McInnes    Level: advanced
378736851e7fSLois Curfman McInnes 
37883c7409f5SSatish Balay .keywords: SNES, set, options, prefix, database
3789a86d99e1SLois Curfman McInnes 
3790a86d99e1SLois Curfman McInnes .seealso: SNESSetFromOptions()
37913c7409f5SSatish Balay @*/
37927087cfbeSBarry Smith PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
37933c7409f5SSatish Balay {
3794dfbe8321SBarry Smith   PetscErrorCode ierr;
37953c7409f5SSatish Balay 
37963a40ed3dSBarry Smith   PetscFunctionBegin;
37970700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3798639f9d9dSBarry Smith   ierr = PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
37991cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
380094b7f48cSBarry Smith   ierr = KSPSetOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38013a40ed3dSBarry Smith   PetscFunctionReturn(0);
38023c7409f5SSatish Balay }
38033c7409f5SSatish Balay 
38044a2ae208SSatish Balay #undef __FUNCT__
38054a2ae208SSatish Balay #define __FUNCT__ "SNESAppendOptionsPrefix"
38063c7409f5SSatish Balay /*@C
3807f525115eSLois Curfman McInnes    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
3808d850072dSLois Curfman McInnes    SNES options in the database.
38093c7409f5SSatish Balay 
38103f9fe445SBarry Smith    Logically Collective on SNES
3811fee21e36SBarry Smith 
3812c7afd0dbSLois Curfman McInnes    Input Parameters:
3813c7afd0dbSLois Curfman McInnes +  snes - the SNES context
3814c7afd0dbSLois Curfman McInnes -  prefix - the prefix to prepend to all option names
3815c7afd0dbSLois Curfman McInnes 
3816d850072dSLois Curfman McInnes    Notes:
3817a83b1b31SSatish Balay    A hyphen (-) must NOT be given at the beginning of the prefix name.
3818c7afd0dbSLois Curfman McInnes    The first character of all runtime options is AUTOMATICALLY the hyphen.
3819d850072dSLois Curfman McInnes 
382036851e7fSLois Curfman McInnes    Level: advanced
382136851e7fSLois Curfman McInnes 
38223c7409f5SSatish Balay .keywords: SNES, append, options, prefix, database
3823a86d99e1SLois Curfman McInnes 
3824a86d99e1SLois Curfman McInnes .seealso: SNESGetOptionsPrefix()
38253c7409f5SSatish Balay @*/
38267087cfbeSBarry Smith PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
38273c7409f5SSatish Balay {
3828dfbe8321SBarry Smith   PetscErrorCode ierr;
38293c7409f5SSatish Balay 
38303a40ed3dSBarry Smith   PetscFunctionBegin;
38310700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3832639f9d9dSBarry Smith   ierr = PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38331cee3971SBarry Smith   if (!snes->ksp) {ierr = SNESGetKSP(snes,&snes->ksp);CHKERRQ(ierr);}
383494b7f48cSBarry Smith   ierr = KSPAppendOptionsPrefix(snes->ksp,prefix);CHKERRQ(ierr);
38353a40ed3dSBarry Smith   PetscFunctionReturn(0);
38363c7409f5SSatish Balay }
38373c7409f5SSatish Balay 
38384a2ae208SSatish Balay #undef __FUNCT__
38394a2ae208SSatish Balay #define __FUNCT__ "SNESGetOptionsPrefix"
38409ab63eb5SSatish Balay /*@C
38413c7409f5SSatish Balay    SNESGetOptionsPrefix - Sets the prefix used for searching for all
38423c7409f5SSatish Balay    SNES options in the database.
38433c7409f5SSatish Balay 
3844c7afd0dbSLois Curfman McInnes    Not Collective
3845c7afd0dbSLois Curfman McInnes 
38463c7409f5SSatish Balay    Input Parameter:
38473c7409f5SSatish Balay .  snes - the SNES context
38483c7409f5SSatish Balay 
38493c7409f5SSatish Balay    Output Parameter:
38503c7409f5SSatish Balay .  prefix - pointer to the prefix string used
38513c7409f5SSatish Balay 
38524ef407dbSRichard Tran Mills    Notes: On the fortran side, the user should pass in a string 'prefix' of
38539ab63eb5SSatish Balay    sufficient length to hold the prefix.
38549ab63eb5SSatish Balay 
385536851e7fSLois Curfman McInnes    Level: advanced
385636851e7fSLois Curfman McInnes 
38573c7409f5SSatish Balay .keywords: SNES, get, options, prefix, database
3858a86d99e1SLois Curfman McInnes 
3859a86d99e1SLois Curfman McInnes .seealso: SNESAppendOptionsPrefix()
38603c7409f5SSatish Balay @*/
38617087cfbeSBarry Smith PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
38623c7409f5SSatish Balay {
3863dfbe8321SBarry Smith   PetscErrorCode ierr;
38643c7409f5SSatish Balay 
38653a40ed3dSBarry Smith   PetscFunctionBegin;
38660700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3867639f9d9dSBarry Smith   ierr = PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);CHKERRQ(ierr);
38683a40ed3dSBarry Smith   PetscFunctionReturn(0);
38693c7409f5SSatish Balay }
38703c7409f5SSatish Balay 
3871b2002411SLois Curfman McInnes 
38724a2ae208SSatish Balay #undef __FUNCT__
38734a2ae208SSatish Balay #define __FUNCT__ "SNESRegister"
38743cea93caSBarry Smith /*@C
38753cea93caSBarry Smith   SNESRegister - See SNESRegisterDynamic()
38763cea93caSBarry Smith 
38777f6c08e0SMatthew Knepley   Level: advanced
38783cea93caSBarry Smith @*/
38797087cfbeSBarry Smith PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3880b2002411SLois Curfman McInnes {
3881e2d1d2b7SBarry Smith   char           fullname[PETSC_MAX_PATH_LEN];
3882dfbe8321SBarry Smith   PetscErrorCode ierr;
3883b2002411SLois Curfman McInnes 
3884b2002411SLois Curfman McInnes   PetscFunctionBegin;
3885b0a32e0cSBarry Smith   ierr = PetscFListConcat(path,name,fullname);CHKERRQ(ierr);
3886c134de8dSSatish Balay   ierr = PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);CHKERRQ(ierr);
3887b2002411SLois Curfman McInnes   PetscFunctionReturn(0);
3888b2002411SLois Curfman McInnes }
3889da9b6338SBarry Smith 
3890da9b6338SBarry Smith #undef __FUNCT__
3891da9b6338SBarry Smith #define __FUNCT__ "SNESTestLocalMin"
38927087cfbeSBarry Smith PetscErrorCode  SNESTestLocalMin(SNES snes)
3893da9b6338SBarry Smith {
3894dfbe8321SBarry Smith   PetscErrorCode ierr;
389577431f27SBarry Smith   PetscInt       N,i,j;
3896da9b6338SBarry Smith   Vec            u,uh,fh;
3897da9b6338SBarry Smith   PetscScalar    value;
3898da9b6338SBarry Smith   PetscReal      norm;
3899da9b6338SBarry Smith 
3900da9b6338SBarry Smith   PetscFunctionBegin;
3901da9b6338SBarry Smith   ierr = SNESGetSolution(snes,&u);CHKERRQ(ierr);
3902da9b6338SBarry Smith   ierr = VecDuplicate(u,&uh);CHKERRQ(ierr);
3903da9b6338SBarry Smith   ierr = VecDuplicate(u,&fh);CHKERRQ(ierr);
3904da9b6338SBarry Smith 
3905da9b6338SBarry Smith   /* currently only works for sequential */
3906da9b6338SBarry Smith   ierr = PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3907da9b6338SBarry Smith   ierr = VecGetSize(u,&N);CHKERRQ(ierr);
3908da9b6338SBarry Smith   for (i=0; i<N; i++) {
3909da9b6338SBarry Smith     ierr = VecCopy(u,uh);CHKERRQ(ierr);
391077431f27SBarry Smith     ierr  = PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);CHKERRQ(ierr);
3911da9b6338SBarry Smith     for (j=-10; j<11; j++) {
3912ccae9161SBarry Smith       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3913da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
39143ab0aad5SBarry Smith       ierr  = SNESComputeFunction(snes,uh,fh);CHKERRQ(ierr);
3915da9b6338SBarry Smith       ierr  = VecNorm(fh,NORM_2,&norm);CHKERRQ(ierr);
391677431f27SBarry Smith       ierr  = PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);CHKERRQ(ierr);
3917da9b6338SBarry Smith       value = -value;
3918da9b6338SBarry Smith       ierr  = VecSetValue(uh,i,value,ADD_VALUES);CHKERRQ(ierr);
3919da9b6338SBarry Smith     }
3920da9b6338SBarry Smith   }
39216bf464f9SBarry Smith   ierr = VecDestroy(&uh);CHKERRQ(ierr);
39226bf464f9SBarry Smith   ierr = VecDestroy(&fh);CHKERRQ(ierr);
3923da9b6338SBarry Smith   PetscFunctionReturn(0);
3924da9b6338SBarry Smith }
392571f87433Sdalcinl 
392671f87433Sdalcinl #undef __FUNCT__
3927fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetUseEW"
392871f87433Sdalcinl /*@
3929fa9f3622SBarry Smith    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
393071f87433Sdalcinl    computing relative tolerance for linear solvers within an inexact
393171f87433Sdalcinl    Newton method.
393271f87433Sdalcinl 
39333f9fe445SBarry Smith    Logically Collective on SNES
393471f87433Sdalcinl 
393571f87433Sdalcinl    Input Parameters:
393671f87433Sdalcinl +  snes - SNES context
393771f87433Sdalcinl -  flag - PETSC_TRUE or PETSC_FALSE
393871f87433Sdalcinl 
393964ba62caSBarry Smith     Options Database:
394064ba62caSBarry Smith +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
394164ba62caSBarry Smith .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
394264ba62caSBarry Smith .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
394364ba62caSBarry Smith .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
394464ba62caSBarry Smith .  -snes_ksp_ew_gamma <gamma> - Sets gamma
394564ba62caSBarry Smith .  -snes_ksp_ew_alpha <alpha> - Sets alpha
394664ba62caSBarry Smith .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
394764ba62caSBarry Smith -  -snes_ksp_ew_threshold <threshold> - Sets threshold
394864ba62caSBarry Smith 
394971f87433Sdalcinl    Notes:
395071f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
395171f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
395271f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
395371f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
395471f87433Sdalcinl    solver.
395571f87433Sdalcinl 
395671f87433Sdalcinl    Level: advanced
395771f87433Sdalcinl 
395871f87433Sdalcinl    Reference:
395971f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
396071f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
396171f87433Sdalcinl 
396271f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
396371f87433Sdalcinl 
3964fa9f3622SBarry Smith .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
396571f87433Sdalcinl @*/
39667087cfbeSBarry Smith PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscBool  flag)
396771f87433Sdalcinl {
396871f87433Sdalcinl   PetscFunctionBegin;
39690700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
3970acfcf0e5SJed Brown   PetscValidLogicalCollectiveBool(snes,flag,2);
397171f87433Sdalcinl   snes->ksp_ewconv = flag;
397271f87433Sdalcinl   PetscFunctionReturn(0);
397371f87433Sdalcinl }
397471f87433Sdalcinl 
397571f87433Sdalcinl #undef __FUNCT__
3976fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetUseEW"
397771f87433Sdalcinl /*@
3978fa9f3622SBarry Smith    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
397971f87433Sdalcinl    for computing relative tolerance for linear solvers within an
398071f87433Sdalcinl    inexact Newton method.
398171f87433Sdalcinl 
398271f87433Sdalcinl    Not Collective
398371f87433Sdalcinl 
398471f87433Sdalcinl    Input Parameter:
398571f87433Sdalcinl .  snes - SNES context
398671f87433Sdalcinl 
398771f87433Sdalcinl    Output Parameter:
398871f87433Sdalcinl .  flag - PETSC_TRUE or PETSC_FALSE
398971f87433Sdalcinl 
399071f87433Sdalcinl    Notes:
399171f87433Sdalcinl    Currently, the default is to use a constant relative tolerance for
399271f87433Sdalcinl    the inner linear solvers.  Alternatively, one can use the
399371f87433Sdalcinl    Eisenstat-Walker method, where the relative convergence tolerance
399471f87433Sdalcinl    is reset at each Newton iteration according progress of the nonlinear
399571f87433Sdalcinl    solver.
399671f87433Sdalcinl 
399771f87433Sdalcinl    Level: advanced
399871f87433Sdalcinl 
399971f87433Sdalcinl    Reference:
400071f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
400171f87433Sdalcinl    inexact Newton method", SISC 17 (1), pp.16-32, 1996.
400271f87433Sdalcinl 
400371f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
400471f87433Sdalcinl 
4005fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
400671f87433Sdalcinl @*/
40077087cfbeSBarry Smith PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscBool  *flag)
400871f87433Sdalcinl {
400971f87433Sdalcinl   PetscFunctionBegin;
40100700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
401171f87433Sdalcinl   PetscValidPointer(flag,2);
401271f87433Sdalcinl   *flag = snes->ksp_ewconv;
401371f87433Sdalcinl   PetscFunctionReturn(0);
401471f87433Sdalcinl }
401571f87433Sdalcinl 
401671f87433Sdalcinl #undef __FUNCT__
4017fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPSetParametersEW"
401871f87433Sdalcinl /*@
4019fa9f3622SBarry Smith    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
402071f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
402171f87433Sdalcinl    Newton method.
402271f87433Sdalcinl 
40233f9fe445SBarry Smith    Logically Collective on SNES
402471f87433Sdalcinl 
402571f87433Sdalcinl    Input Parameters:
402671f87433Sdalcinl +    snes - SNES context
402771f87433Sdalcinl .    version - version 1, 2 (default is 2) or 3
402871f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
402971f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
403071f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
403171f87433Sdalcinl              (0 <= gamma2 <= 1)
403271f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
403371f87433Sdalcinl .    alpha2 - power for safeguard
403471f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
403571f87433Sdalcinl 
403671f87433Sdalcinl    Note:
403771f87433Sdalcinl    Version 3 was contributed by Luis Chacon, June 2006.
403871f87433Sdalcinl 
403971f87433Sdalcinl    Use PETSC_DEFAULT to retain the default for any of the parameters.
404071f87433Sdalcinl 
404171f87433Sdalcinl    Level: advanced
404271f87433Sdalcinl 
404371f87433Sdalcinl    Reference:
404471f87433Sdalcinl    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
404571f87433Sdalcinl    inexact Newton method", Utah State University Math. Stat. Dept. Res.
404671f87433Sdalcinl    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
404771f87433Sdalcinl 
404871f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
404971f87433Sdalcinl 
4050fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
405171f87433Sdalcinl @*/
40527087cfbeSBarry Smith PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
405371f87433Sdalcinl 							    PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
405471f87433Sdalcinl {
4055fa9f3622SBarry Smith   SNESKSPEW *kctx;
405671f87433Sdalcinl   PetscFunctionBegin;
40570700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4058fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4059e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
4060c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(snes,version,2);
4061c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_0,3);
4062c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,rtol_max,4);
4063c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,gamma,5);
4064c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha,6);
4065c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,alpha2,7);
4066c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(snes,threshold,8);
406771f87433Sdalcinl 
406871f87433Sdalcinl   if (version != PETSC_DEFAULT)   kctx->version   = version;
406971f87433Sdalcinl   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
407071f87433Sdalcinl   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
407171f87433Sdalcinl   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
407271f87433Sdalcinl   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
407371f87433Sdalcinl   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
407471f87433Sdalcinl   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
407571f87433Sdalcinl 
407671f87433Sdalcinl   if (kctx->version < 1 || kctx->version > 3) {
4077e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
407871f87433Sdalcinl   }
407971f87433Sdalcinl   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
4080e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
408171f87433Sdalcinl   }
408271f87433Sdalcinl   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
4083e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
408471f87433Sdalcinl   }
408571f87433Sdalcinl   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
4086e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
408771f87433Sdalcinl   }
408871f87433Sdalcinl   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
4089e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
409071f87433Sdalcinl   }
409171f87433Sdalcinl   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
4092e32f2f54SBarry Smith     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
409371f87433Sdalcinl   }
409471f87433Sdalcinl   PetscFunctionReturn(0);
409571f87433Sdalcinl }
409671f87433Sdalcinl 
409771f87433Sdalcinl #undef __FUNCT__
4098fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPGetParametersEW"
409971f87433Sdalcinl /*@
4100fa9f3622SBarry Smith    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
410171f87433Sdalcinl    convergence criteria for the linear solvers within an inexact
410271f87433Sdalcinl    Newton method.
410371f87433Sdalcinl 
410471f87433Sdalcinl    Not Collective
410571f87433Sdalcinl 
410671f87433Sdalcinl    Input Parameters:
410771f87433Sdalcinl      snes - SNES context
410871f87433Sdalcinl 
410971f87433Sdalcinl    Output Parameters:
411071f87433Sdalcinl +    version - version 1, 2 (default is 2) or 3
411171f87433Sdalcinl .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
411271f87433Sdalcinl .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
411371f87433Sdalcinl .    gamma - multiplicative factor for version 2 rtol computation
411471f87433Sdalcinl              (0 <= gamma2 <= 1)
411571f87433Sdalcinl .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
411671f87433Sdalcinl .    alpha2 - power for safeguard
411771f87433Sdalcinl -    threshold - threshold for imposing safeguard (0 < threshold < 1)
411871f87433Sdalcinl 
411971f87433Sdalcinl    Level: advanced
412071f87433Sdalcinl 
412171f87433Sdalcinl .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
412271f87433Sdalcinl 
4123fa9f3622SBarry Smith .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
412471f87433Sdalcinl @*/
41257087cfbeSBarry Smith PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
412671f87433Sdalcinl 							    PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
412771f87433Sdalcinl {
4128fa9f3622SBarry Smith   SNESKSPEW *kctx;
412971f87433Sdalcinl   PetscFunctionBegin;
41300700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4131fa9f3622SBarry Smith   kctx = (SNESKSPEW*)snes->kspconvctx;
4132e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
413371f87433Sdalcinl   if(version)   *version   = kctx->version;
413471f87433Sdalcinl   if(rtol_0)    *rtol_0    = kctx->rtol_0;
413571f87433Sdalcinl   if(rtol_max)  *rtol_max  = kctx->rtol_max;
413671f87433Sdalcinl   if(gamma)     *gamma     = kctx->gamma;
413771f87433Sdalcinl   if(alpha)     *alpha     = kctx->alpha;
413871f87433Sdalcinl   if(alpha2)    *alpha2    = kctx->alpha2;
413971f87433Sdalcinl   if(threshold) *threshold = kctx->threshold;
414071f87433Sdalcinl   PetscFunctionReturn(0);
414171f87433Sdalcinl }
414271f87433Sdalcinl 
414371f87433Sdalcinl #undef __FUNCT__
4144fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PreSolve"
4145fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
414671f87433Sdalcinl {
414771f87433Sdalcinl   PetscErrorCode ierr;
4148fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
414971f87433Sdalcinl   PetscReal      rtol=PETSC_DEFAULT,stol;
415071f87433Sdalcinl 
415171f87433Sdalcinl   PetscFunctionBegin;
4152e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
415371f87433Sdalcinl   if (!snes->iter) { /* first time in, so use the original user rtol */
415471f87433Sdalcinl     rtol = kctx->rtol_0;
415571f87433Sdalcinl   } else {
415671f87433Sdalcinl     if (kctx->version == 1) {
415771f87433Sdalcinl       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
415871f87433Sdalcinl       if (rtol < 0.0) rtol = -rtol;
415971f87433Sdalcinl       stol = pow(kctx->rtol_last,kctx->alpha2);
416071f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
416171f87433Sdalcinl     } else if (kctx->version == 2) {
416271f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
416371f87433Sdalcinl       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
416471f87433Sdalcinl       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
416571f87433Sdalcinl     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
416671f87433Sdalcinl       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
416771f87433Sdalcinl       /* safeguard: avoid sharp decrease of rtol */
416871f87433Sdalcinl       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
416971f87433Sdalcinl       stol = PetscMax(rtol,stol);
417071f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
417171f87433Sdalcinl       /* safeguard: avoid oversolving */
417271f87433Sdalcinl       stol = kctx->gamma*(snes->ttol)/snes->norm;
417371f87433Sdalcinl       stol = PetscMax(rtol,stol);
417471f87433Sdalcinl       rtol = PetscMin(kctx->rtol_0,stol);
4175e32f2f54SBarry Smith     } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
417671f87433Sdalcinl   }
417771f87433Sdalcinl   /* safeguard: avoid rtol greater than one */
417871f87433Sdalcinl   rtol = PetscMin(rtol,kctx->rtol_max);
417971f87433Sdalcinl   ierr = KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
418071f87433Sdalcinl   ierr = PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);CHKERRQ(ierr);
418171f87433Sdalcinl   PetscFunctionReturn(0);
418271f87433Sdalcinl }
418371f87433Sdalcinl 
418471f87433Sdalcinl #undef __FUNCT__
4185fa9f3622SBarry Smith #define __FUNCT__ "SNESKSPEW_PostSolve"
4186fa9f3622SBarry Smith static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
418771f87433Sdalcinl {
418871f87433Sdalcinl   PetscErrorCode ierr;
4189fa9f3622SBarry Smith   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
419071f87433Sdalcinl   PCSide         pcside;
419171f87433Sdalcinl   Vec            lres;
419271f87433Sdalcinl 
419371f87433Sdalcinl   PetscFunctionBegin;
4194e32f2f54SBarry Smith   if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
419571f87433Sdalcinl   ierr = KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);CHKERRQ(ierr);
419671f87433Sdalcinl   ierr = SNESGetFunctionNorm(snes,&kctx->norm_last);CHKERRQ(ierr);
419771f87433Sdalcinl   if (kctx->version == 1) {
4198b037da10SBarry Smith     ierr = KSPGetPCSide(ksp,&pcside);CHKERRQ(ierr);
419971f87433Sdalcinl     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
420071f87433Sdalcinl       /* KSP residual is true linear residual */
420171f87433Sdalcinl       ierr = KSPGetResidualNorm(ksp,&kctx->lresid_last);CHKERRQ(ierr);
420271f87433Sdalcinl     } else {
420371f87433Sdalcinl       /* KSP residual is preconditioned residual */
420471f87433Sdalcinl       /* compute true linear residual norm */
420571f87433Sdalcinl       ierr = VecDuplicate(b,&lres);CHKERRQ(ierr);
420671f87433Sdalcinl       ierr = MatMult(snes->jacobian,x,lres);CHKERRQ(ierr);
420771f87433Sdalcinl       ierr = VecAYPX(lres,-1.0,b);CHKERRQ(ierr);
420871f87433Sdalcinl       ierr = VecNorm(lres,NORM_2,&kctx->lresid_last);CHKERRQ(ierr);
42096bf464f9SBarry Smith       ierr = VecDestroy(&lres);CHKERRQ(ierr);
421071f87433Sdalcinl     }
421171f87433Sdalcinl   }
421271f87433Sdalcinl   PetscFunctionReturn(0);
421371f87433Sdalcinl }
421471f87433Sdalcinl 
421571f87433Sdalcinl #undef __FUNCT__
421671f87433Sdalcinl #define __FUNCT__ "SNES_KSPSolve"
421771f87433Sdalcinl PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
421871f87433Sdalcinl {
421971f87433Sdalcinl   PetscErrorCode ierr;
422071f87433Sdalcinl 
422171f87433Sdalcinl   PetscFunctionBegin;
4222fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PreSolve(snes,ksp,b,x);CHKERRQ(ierr);  }
422371f87433Sdalcinl   ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
4224fa9f3622SBarry Smith   if (snes->ksp_ewconv) { ierr = SNESKSPEW_PostSolve(snes,ksp,b,x);CHKERRQ(ierr); }
422571f87433Sdalcinl   PetscFunctionReturn(0);
422671f87433Sdalcinl }
42276c699258SBarry Smith 
42286c699258SBarry Smith #undef __FUNCT__
42296c699258SBarry Smith #define __FUNCT__ "SNESSetDM"
42306c699258SBarry Smith /*@
42316c699258SBarry Smith    SNESSetDM - Sets the DM that may be used by some preconditioners
42326c699258SBarry Smith 
42333f9fe445SBarry Smith    Logically Collective on SNES
42346c699258SBarry Smith 
42356c699258SBarry Smith    Input Parameters:
42366c699258SBarry Smith +  snes - the preconditioner context
42376c699258SBarry Smith -  dm - the dm
42386c699258SBarry Smith 
42396c699258SBarry Smith    Level: intermediate
42406c699258SBarry Smith 
42416c699258SBarry Smith 
42426c699258SBarry Smith .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
42436c699258SBarry Smith @*/
42447087cfbeSBarry Smith PetscErrorCode  SNESSetDM(SNES snes,DM dm)
42456c699258SBarry Smith {
42466c699258SBarry Smith   PetscErrorCode ierr;
4247345fed2cSBarry Smith   KSP            ksp;
42486cab3a1bSJed Brown   SNESDM         sdm;
42496c699258SBarry Smith 
42506c699258SBarry Smith   PetscFunctionBegin;
42510700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4252d0660788SBarry Smith   if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);}
42536cab3a1bSJed Brown   if (snes->dm) {               /* Move the SNESDM context over to the new DM unless the new DM already has one */
42546cab3a1bSJed Brown     PetscContainer oldcontainer,container;
42556cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)snes->dm,"SNESDM",(PetscObject*)&oldcontainer);CHKERRQ(ierr);
42566cab3a1bSJed Brown     ierr = PetscObjectQuery((PetscObject)dm,"SNESDM",(PetscObject*)&container);CHKERRQ(ierr);
42576cab3a1bSJed Brown     if (oldcontainer && !container) {
42586cab3a1bSJed Brown       ierr = DMSNESCopyContext(snes->dm,dm);CHKERRQ(ierr);
42596cab3a1bSJed Brown       ierr = DMSNESGetContext(snes->dm,&sdm);CHKERRQ(ierr);
42606cab3a1bSJed Brown       if (sdm->originaldm == snes->dm) { /* Grant write privileges to the replacement DM */
42616cab3a1bSJed Brown         sdm->originaldm = dm;
42626cab3a1bSJed Brown       }
42636cab3a1bSJed Brown     }
42646bf464f9SBarry Smith     ierr = DMDestroy(&snes->dm);CHKERRQ(ierr);
42656cab3a1bSJed Brown   }
42666c699258SBarry Smith   snes->dm = dm;
4267345fed2cSBarry Smith   ierr = SNESGetKSP(snes,&ksp);CHKERRQ(ierr);
4268345fed2cSBarry Smith   ierr = KSPSetDM(ksp,dm);CHKERRQ(ierr);
4269f22f69f0SBarry Smith   ierr = KSPSetDMActive(ksp,PETSC_FALSE);CHKERRQ(ierr);
42702c155ee1SBarry Smith   if (snes->pc) {
42712c155ee1SBarry Smith     ierr = SNESSetDM(snes->pc, snes->dm);CHKERRQ(ierr);
42722c155ee1SBarry Smith   }
42736c699258SBarry Smith   PetscFunctionReturn(0);
42746c699258SBarry Smith }
42756c699258SBarry Smith 
42766c699258SBarry Smith #undef __FUNCT__
42776c699258SBarry Smith #define __FUNCT__ "SNESGetDM"
42786c699258SBarry Smith /*@
42796c699258SBarry Smith    SNESGetDM - Gets the DM that may be used by some preconditioners
42806c699258SBarry Smith 
42813f9fe445SBarry Smith    Not Collective but DM obtained is parallel on SNES
42826c699258SBarry Smith 
42836c699258SBarry Smith    Input Parameter:
42846c699258SBarry Smith . snes - the preconditioner context
42856c699258SBarry Smith 
42866c699258SBarry Smith    Output Parameter:
42876c699258SBarry Smith .  dm - the dm
42886c699258SBarry Smith 
42896c699258SBarry Smith    Level: intermediate
42906c699258SBarry Smith 
42916c699258SBarry Smith 
42926c699258SBarry Smith .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
42936c699258SBarry Smith @*/
42947087cfbeSBarry Smith PetscErrorCode  SNESGetDM(SNES snes,DM *dm)
42956c699258SBarry Smith {
42966cab3a1bSJed Brown   PetscErrorCode ierr;
42976cab3a1bSJed Brown 
42986c699258SBarry Smith   PetscFunctionBegin;
42990700a824SBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
43006cab3a1bSJed Brown   if (!snes->dm) {
43016cab3a1bSJed Brown     ierr = DMShellCreate(((PetscObject)snes)->comm,&snes->dm);CHKERRQ(ierr);
43026cab3a1bSJed Brown   }
43036c699258SBarry Smith   *dm = snes->dm;
43046c699258SBarry Smith   PetscFunctionReturn(0);
43056c699258SBarry Smith }
43060807856dSBarry Smith 
430731823bd8SMatthew G Knepley #undef __FUNCT__
430831823bd8SMatthew G Knepley #define __FUNCT__ "SNESSetPC"
430931823bd8SMatthew G Knepley /*@
4310fd4b34e9SJed Brown   SNESSetPC - Sets the nonlinear preconditioner to be used.
431131823bd8SMatthew G Knepley 
431231823bd8SMatthew G Knepley   Collective on SNES
431331823bd8SMatthew G Knepley 
431431823bd8SMatthew G Knepley   Input Parameters:
431531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate()
431631823bd8SMatthew G Knepley - pc   - the preconditioner object
431731823bd8SMatthew G Knepley 
431831823bd8SMatthew G Knepley   Notes:
431931823bd8SMatthew G Knepley   Use SNESGetPC() to retrieve the preconditioner context (for example,
432031823bd8SMatthew G Knepley   to configure it using the API).
432131823bd8SMatthew G Knepley 
432231823bd8SMatthew G Knepley   Level: developer
432331823bd8SMatthew G Knepley 
432431823bd8SMatthew G Knepley .keywords: SNES, set, precondition
432531823bd8SMatthew G Knepley .seealso: SNESGetPC()
432631823bd8SMatthew G Knepley @*/
432731823bd8SMatthew G Knepley PetscErrorCode SNESSetPC(SNES snes, SNES pc)
432831823bd8SMatthew G Knepley {
432931823bd8SMatthew G Knepley   PetscErrorCode ierr;
433031823bd8SMatthew G Knepley 
433131823bd8SMatthew G Knepley   PetscFunctionBegin;
433231823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
433331823bd8SMatthew G Knepley   PetscValidHeaderSpecific(pc, SNES_CLASSID, 2);
433431823bd8SMatthew G Knepley   PetscCheckSameComm(snes, 1, pc, 2);
433531823bd8SMatthew G Knepley   ierr = PetscObjectReference((PetscObject) pc);CHKERRQ(ierr);
4336bf11d3b6SBarry Smith   ierr = SNESDestroy(&snes->pc);CHKERRQ(ierr);
433731823bd8SMatthew G Knepley   snes->pc = pc;
433831823bd8SMatthew G Knepley   ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
433931823bd8SMatthew G Knepley   PetscFunctionReturn(0);
434031823bd8SMatthew G Knepley }
434131823bd8SMatthew G Knepley 
434231823bd8SMatthew G Knepley #undef __FUNCT__
434331823bd8SMatthew G Knepley #define __FUNCT__ "SNESGetPC"
434431823bd8SMatthew G Knepley /*@
4345fd4b34e9SJed Brown   SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
434631823bd8SMatthew G Knepley 
434731823bd8SMatthew G Knepley   Not Collective
434831823bd8SMatthew G Knepley 
434931823bd8SMatthew G Knepley   Input Parameter:
435031823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate()
435131823bd8SMatthew G Knepley 
435231823bd8SMatthew G Knepley   Output Parameter:
435331823bd8SMatthew G Knepley . pc - preconditioner context
435431823bd8SMatthew G Knepley 
435531823bd8SMatthew G Knepley   Level: developer
435631823bd8SMatthew G Knepley 
435731823bd8SMatthew G Knepley .keywords: SNES, get, preconditioner
435831823bd8SMatthew G Knepley .seealso: SNESSetPC()
435931823bd8SMatthew G Knepley @*/
436031823bd8SMatthew G Knepley PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
436131823bd8SMatthew G Knepley {
436231823bd8SMatthew G Knepley   PetscErrorCode ierr;
436331823bd8SMatthew G Knepley 
436431823bd8SMatthew G Knepley   PetscFunctionBegin;
436531823bd8SMatthew G Knepley   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
436631823bd8SMatthew G Knepley   PetscValidPointer(pc, 2);
436731823bd8SMatthew G Knepley   if (!snes->pc) {
436831823bd8SMatthew G Knepley     ierr = SNESCreate(((PetscObject) snes)->comm, &snes->pc);CHKERRQ(ierr);
43694a0c5b0cSMatthew G Knepley     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);CHKERRQ(ierr);
437031823bd8SMatthew G Knepley     ierr = PetscLogObjectParent(snes, snes->pc);CHKERRQ(ierr);
437131823bd8SMatthew G Knepley   }
437231823bd8SMatthew G Knepley   *pc = snes->pc;
437331823bd8SMatthew G Knepley   PetscFunctionReturn(0);
437431823bd8SMatthew G Knepley }
437531823bd8SMatthew G Knepley 
43769e764e56SPeter Brune #undef __FUNCT__
4377f1c6b773SPeter Brune #define __FUNCT__ "SNESSetSNESLineSearch"
43789e764e56SPeter Brune /*@
43798141a3b9SPeter Brune   SNESSetSNESLineSearch - Sets the linesearch on the SNES instance.
43809e764e56SPeter Brune 
43819e764e56SPeter Brune   Collective on SNES
43829e764e56SPeter Brune 
43839e764e56SPeter Brune   Input Parameters:
43849e764e56SPeter Brune + snes - iterative context obtained from SNESCreate()
43859e764e56SPeter Brune - linesearch   - the linesearch object
43869e764e56SPeter Brune 
43879e764e56SPeter Brune   Notes:
4388f1c6b773SPeter Brune   Use SNESGetSNESLineSearch() to retrieve the preconditioner context (for example,
43899e764e56SPeter Brune   to configure it using the API).
43909e764e56SPeter Brune 
43919e764e56SPeter Brune   Level: developer
43929e764e56SPeter Brune 
43939e764e56SPeter Brune .keywords: SNES, set, linesearch
4394f1c6b773SPeter Brune .seealso: SNESGetSNESLineSearch()
43959e764e56SPeter Brune @*/
4396f1c6b773SPeter Brune PetscErrorCode SNESSetSNESLineSearch(SNES snes, SNESLineSearch linesearch)
43979e764e56SPeter Brune {
43989e764e56SPeter Brune   PetscErrorCode ierr;
43999e764e56SPeter Brune 
44009e764e56SPeter Brune   PetscFunctionBegin;
44019e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
4402f1c6b773SPeter Brune   PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2);
44039e764e56SPeter Brune   PetscCheckSameComm(snes, 1, linesearch, 2);
44049e764e56SPeter Brune   ierr = PetscObjectReference((PetscObject) linesearch);CHKERRQ(ierr);
4405f1c6b773SPeter Brune   ierr = SNESLineSearchDestroy(&snes->linesearch);CHKERRQ(ierr);
44069e764e56SPeter Brune   snes->linesearch = linesearch;
44079e764e56SPeter Brune   ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44089e764e56SPeter Brune   PetscFunctionReturn(0);
44099e764e56SPeter Brune }
44109e764e56SPeter Brune 
44119e764e56SPeter Brune #undef __FUNCT__
4412f1c6b773SPeter Brune #define __FUNCT__ "SNESGetSNESLineSearch"
4413ea5d4fccSPeter Brune /*@C
44148141a3b9SPeter Brune   SNESGetSNESLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch()
44158141a3b9SPeter Brune   or creates a default line search instance associated with the SNES and returns it.
44169e764e56SPeter Brune 
44179e764e56SPeter Brune   Not Collective
44189e764e56SPeter Brune 
44199e764e56SPeter Brune   Input Parameter:
44209e764e56SPeter Brune . snes - iterative context obtained from SNESCreate()
44219e764e56SPeter Brune 
44229e764e56SPeter Brune   Output Parameter:
44239e764e56SPeter Brune . linesearch - linesearch context
44249e764e56SPeter Brune 
44259e764e56SPeter Brune   Level: developer
44269e764e56SPeter Brune 
44279e764e56SPeter Brune .keywords: SNES, get, linesearch
4428f1c6b773SPeter Brune .seealso: SNESSetSNESLineSearch()
44299e764e56SPeter Brune @*/
4430f1c6b773SPeter Brune PetscErrorCode SNESGetSNESLineSearch(SNES snes, SNESLineSearch *linesearch)
44319e764e56SPeter Brune {
44329e764e56SPeter Brune   PetscErrorCode ierr;
44339e764e56SPeter Brune   const char     *optionsprefix;
44349e764e56SPeter Brune 
44359e764e56SPeter Brune   PetscFunctionBegin;
44369e764e56SPeter Brune   PetscValidHeaderSpecific(snes, SNES_CLASSID, 1);
44379e764e56SPeter Brune   PetscValidPointer(linesearch, 2);
44389e764e56SPeter Brune   if (!snes->linesearch) {
44399e764e56SPeter Brune     ierr = SNESGetOptionsPrefix(snes, &optionsprefix);CHKERRQ(ierr);
4440f1c6b773SPeter Brune     ierr = SNESLineSearchCreate(((PetscObject) snes)->comm, &snes->linesearch);CHKERRQ(ierr);
4441f1c6b773SPeter Brune     ierr = SNESLineSearchSetSNES(snes->linesearch, snes);CHKERRQ(ierr);
4442b1dca40bSPeter Brune     ierr = SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix);CHKERRQ(ierr);
44439e764e56SPeter Brune     ierr = PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1);CHKERRQ(ierr);
44449e764e56SPeter Brune     ierr = PetscLogObjectParent(snes, snes->linesearch);CHKERRQ(ierr);
44459e764e56SPeter Brune   }
44469e764e56SPeter Brune   *linesearch = snes->linesearch;
44479e764e56SPeter Brune   PetscFunctionReturn(0);
44489e764e56SPeter Brune }
44499e764e56SPeter Brune 
445069b4f73cSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE)
4451c6db04a5SJed Brown #include <mex.h>
445269b4f73cSBarry Smith 
44538f6e6473SBarry Smith typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
44548f6e6473SBarry Smith 
44550807856dSBarry Smith #undef __FUNCT__
44560807856dSBarry Smith #define __FUNCT__ "SNESComputeFunction_Matlab"
44570807856dSBarry Smith /*
44580807856dSBarry Smith    SNESComputeFunction_Matlab - Calls the function that has been set with
44590807856dSBarry Smith                          SNESSetFunctionMatlab().
44600807856dSBarry Smith 
44610807856dSBarry Smith    Collective on SNES
44620807856dSBarry Smith 
44630807856dSBarry Smith    Input Parameters:
44640807856dSBarry Smith +  snes - the SNES context
44650807856dSBarry Smith -  x - input vector
44660807856dSBarry Smith 
44670807856dSBarry Smith    Output Parameter:
44680807856dSBarry Smith .  y - function vector, as set by SNESSetFunction()
44690807856dSBarry Smith 
44700807856dSBarry Smith    Notes:
44710807856dSBarry Smith    SNESComputeFunction() is typically used within nonlinear solvers
44720807856dSBarry Smith    implementations, so most users would not generally call this routine
44730807856dSBarry Smith    themselves.
44740807856dSBarry Smith 
44750807856dSBarry Smith    Level: developer
44760807856dSBarry Smith 
44770807856dSBarry Smith .keywords: SNES, nonlinear, compute, function
44780807856dSBarry Smith 
44790807856dSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
448061b2408cSBarry Smith */
44817087cfbeSBarry Smith PetscErrorCode  SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
44820807856dSBarry Smith {
4483e650e774SBarry Smith   PetscErrorCode    ierr;
44848f6e6473SBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
44858f6e6473SBarry Smith   int               nlhs = 1,nrhs = 5;
44868f6e6473SBarry Smith   mxArray	    *plhs[1],*prhs[5];
448791621f2eSBarry Smith   long long int     lx = 0,ly = 0,ls = 0;
4488e650e774SBarry Smith 
44890807856dSBarry Smith   PetscFunctionBegin;
44900807856dSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
44910807856dSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
44920807856dSBarry Smith   PetscValidHeaderSpecific(y,VEC_CLASSID,3);
44930807856dSBarry Smith   PetscCheckSameComm(snes,1,x,2);
44940807856dSBarry Smith   PetscCheckSameComm(snes,1,y,3);
44950807856dSBarry Smith 
44960807856dSBarry Smith   /* call Matlab function in ctx with arguments x and y */
4497e650e774SBarry Smith 
449891621f2eSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4499e650e774SBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4500e650e774SBarry Smith   ierr = PetscMemcpy(&ly,&y,sizeof(x));CHKERRQ(ierr);
450191621f2eSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
450291621f2eSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
450391621f2eSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)ly);
45048f6e6473SBarry Smith   prhs[3] =  mxCreateString(sctx->funcname);
45058f6e6473SBarry Smith   prhs[4] =  sctx->ctx;
4506b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");CHKERRQ(ierr);
4507e650e774SBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4508e650e774SBarry Smith   mxDestroyArray(prhs[0]);
4509e650e774SBarry Smith   mxDestroyArray(prhs[1]);
4510e650e774SBarry Smith   mxDestroyArray(prhs[2]);
45118f6e6473SBarry Smith   mxDestroyArray(prhs[3]);
4512e650e774SBarry Smith   mxDestroyArray(plhs[0]);
45130807856dSBarry Smith   PetscFunctionReturn(0);
45140807856dSBarry Smith }
45150807856dSBarry Smith 
45160807856dSBarry Smith 
45170807856dSBarry Smith #undef __FUNCT__
45180807856dSBarry Smith #define __FUNCT__ "SNESSetFunctionMatlab"
451961b2408cSBarry Smith /*
45200807856dSBarry Smith    SNESSetFunctionMatlab - Sets the function evaluation routine and function
45210807856dSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4522e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
45230807856dSBarry Smith 
45240807856dSBarry Smith    Logically Collective on SNES
45250807856dSBarry Smith 
45260807856dSBarry Smith    Input Parameters:
45270807856dSBarry Smith +  snes - the SNES context
45280807856dSBarry Smith .  r - vector to store function value
45290807856dSBarry Smith -  func - function evaluation routine
45300807856dSBarry Smith 
45310807856dSBarry Smith    Calling sequence of func:
453261b2408cSBarry Smith $    func (SNES snes,Vec x,Vec f,void *ctx);
45330807856dSBarry Smith 
45340807856dSBarry Smith 
45350807856dSBarry Smith    Notes:
45360807856dSBarry Smith    The Newton-like methods typically solve linear systems of the form
45370807856dSBarry Smith $      f'(x) x = -f(x),
45380807856dSBarry Smith    where f'(x) denotes the Jacobian matrix and f(x) is the function.
45390807856dSBarry Smith 
45400807856dSBarry Smith    Level: beginner
45410807856dSBarry Smith 
45420807856dSBarry Smith .keywords: SNES, nonlinear, set, function
45430807856dSBarry Smith 
45440807856dSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
454561b2408cSBarry Smith */
45467087cfbeSBarry Smith PetscErrorCode  SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
45470807856dSBarry Smith {
45480807856dSBarry Smith   PetscErrorCode    ierr;
45498f6e6473SBarry Smith   SNESMatlabContext *sctx;
45500807856dSBarry Smith 
45510807856dSBarry Smith   PetscFunctionBegin;
45528f6e6473SBarry Smith   /* currently sctx is memory bleed */
45538f6e6473SBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
45548f6e6473SBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
45558f6e6473SBarry Smith   /*
45568f6e6473SBarry Smith      This should work, but it doesn't
45578f6e6473SBarry Smith   sctx->ctx = ctx;
45588f6e6473SBarry Smith   mexMakeArrayPersistent(sctx->ctx);
45598f6e6473SBarry Smith   */
45608f6e6473SBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
45618f6e6473SBarry Smith   ierr = SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);CHKERRQ(ierr);
45620807856dSBarry Smith   PetscFunctionReturn(0);
45630807856dSBarry Smith }
456469b4f73cSBarry Smith 
456561b2408cSBarry Smith #undef __FUNCT__
456661b2408cSBarry Smith #define __FUNCT__ "SNESComputeJacobian_Matlab"
456761b2408cSBarry Smith /*
456861b2408cSBarry Smith    SNESComputeJacobian_Matlab - Calls the function that has been set with
456961b2408cSBarry Smith                          SNESSetJacobianMatlab().
457061b2408cSBarry Smith 
457161b2408cSBarry Smith    Collective on SNES
457261b2408cSBarry Smith 
457361b2408cSBarry Smith    Input Parameters:
457461b2408cSBarry Smith +  snes - the SNES context
457561b2408cSBarry Smith .  x - input vector
457661b2408cSBarry Smith .  A, B - the matrices
457761b2408cSBarry Smith -  ctx - user context
457861b2408cSBarry Smith 
457961b2408cSBarry Smith    Output Parameter:
458061b2408cSBarry Smith .  flag - structure of the matrix
458161b2408cSBarry Smith 
458261b2408cSBarry Smith    Level: developer
458361b2408cSBarry Smith 
458461b2408cSBarry Smith .keywords: SNES, nonlinear, compute, function
458561b2408cSBarry Smith 
458661b2408cSBarry Smith .seealso: SNESSetFunction(), SNESGetFunction()
458761b2408cSBarry Smith @*/
45887087cfbeSBarry Smith PetscErrorCode  SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
458961b2408cSBarry Smith {
459061b2408cSBarry Smith   PetscErrorCode    ierr;
459161b2408cSBarry Smith   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
459261b2408cSBarry Smith   int               nlhs = 2,nrhs = 6;
459361b2408cSBarry Smith   mxArray	    *plhs[2],*prhs[6];
459461b2408cSBarry Smith   long long int     lx = 0,lA = 0,ls = 0, lB = 0;
459561b2408cSBarry Smith 
459661b2408cSBarry Smith   PetscFunctionBegin;
459761b2408cSBarry Smith   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
459861b2408cSBarry Smith   PetscValidHeaderSpecific(x,VEC_CLASSID,2);
459961b2408cSBarry Smith 
460061b2408cSBarry Smith   /* call Matlab function in ctx with arguments x and y */
460161b2408cSBarry Smith 
460261b2408cSBarry Smith   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
460361b2408cSBarry Smith   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
460461b2408cSBarry Smith   ierr = PetscMemcpy(&lA,A,sizeof(x));CHKERRQ(ierr);
460561b2408cSBarry Smith   ierr = PetscMemcpy(&lB,B,sizeof(x));CHKERRQ(ierr);
460661b2408cSBarry Smith   prhs[0] =  mxCreateDoubleScalar((double)ls);
460761b2408cSBarry Smith   prhs[1] =  mxCreateDoubleScalar((double)lx);
460861b2408cSBarry Smith   prhs[2] =  mxCreateDoubleScalar((double)lA);
460961b2408cSBarry Smith   prhs[3] =  mxCreateDoubleScalar((double)lB);
461061b2408cSBarry Smith   prhs[4] =  mxCreateString(sctx->funcname);
461161b2408cSBarry Smith   prhs[5] =  sctx->ctx;
4612b807a863SBarry Smith   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");CHKERRQ(ierr);
461361b2408cSBarry Smith   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
461461b2408cSBarry Smith   *flag   =  (MatStructure) mxGetScalar(plhs[1]);CHKERRQ(ierr);
461561b2408cSBarry Smith   mxDestroyArray(prhs[0]);
461661b2408cSBarry Smith   mxDestroyArray(prhs[1]);
461761b2408cSBarry Smith   mxDestroyArray(prhs[2]);
461861b2408cSBarry Smith   mxDestroyArray(prhs[3]);
461961b2408cSBarry Smith   mxDestroyArray(prhs[4]);
462061b2408cSBarry Smith   mxDestroyArray(plhs[0]);
462161b2408cSBarry Smith   mxDestroyArray(plhs[1]);
462261b2408cSBarry Smith   PetscFunctionReturn(0);
462361b2408cSBarry Smith }
462461b2408cSBarry Smith 
462561b2408cSBarry Smith 
462661b2408cSBarry Smith #undef __FUNCT__
462761b2408cSBarry Smith #define __FUNCT__ "SNESSetJacobianMatlab"
462861b2408cSBarry Smith /*
462961b2408cSBarry Smith    SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
463061b2408cSBarry Smith    vector for use by the SNES routines in solving systems of nonlinear
4631e3c5b3baSBarry Smith    equations from MATLAB. Here the function is a string containing the name of a MATLAB function
463261b2408cSBarry Smith 
463361b2408cSBarry Smith    Logically Collective on SNES
463461b2408cSBarry Smith 
463561b2408cSBarry Smith    Input Parameters:
463661b2408cSBarry Smith +  snes - the SNES context
463761b2408cSBarry Smith .  A,B - Jacobian matrices
463861b2408cSBarry Smith .  func - function evaluation routine
463961b2408cSBarry Smith -  ctx - user context
464061b2408cSBarry Smith 
464161b2408cSBarry Smith    Calling sequence of func:
464261b2408cSBarry Smith $    flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
464361b2408cSBarry Smith 
464461b2408cSBarry Smith 
464561b2408cSBarry Smith    Level: developer
464661b2408cSBarry Smith 
464761b2408cSBarry Smith .keywords: SNES, nonlinear, set, function
464861b2408cSBarry Smith 
464961b2408cSBarry Smith .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
465061b2408cSBarry Smith */
46517087cfbeSBarry Smith PetscErrorCode  SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
465261b2408cSBarry Smith {
465361b2408cSBarry Smith   PetscErrorCode    ierr;
465461b2408cSBarry Smith   SNESMatlabContext *sctx;
465561b2408cSBarry Smith 
465661b2408cSBarry Smith   PetscFunctionBegin;
465761b2408cSBarry Smith   /* currently sctx is memory bleed */
465861b2408cSBarry Smith   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
465961b2408cSBarry Smith   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
466061b2408cSBarry Smith   /*
466161b2408cSBarry Smith      This should work, but it doesn't
466261b2408cSBarry Smith   sctx->ctx = ctx;
466361b2408cSBarry Smith   mexMakeArrayPersistent(sctx->ctx);
466461b2408cSBarry Smith   */
466561b2408cSBarry Smith   sctx->ctx = mxDuplicateArray(ctx);
466661b2408cSBarry Smith   ierr = SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);CHKERRQ(ierr);
466761b2408cSBarry Smith   PetscFunctionReturn(0);
466861b2408cSBarry Smith }
466969b4f73cSBarry Smith 
4670f9eb7ae2SShri Abhyankar #undef __FUNCT__
4671f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitor_Matlab"
4672f9eb7ae2SShri Abhyankar /*
4673f9eb7ae2SShri Abhyankar    SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
4674f9eb7ae2SShri Abhyankar 
4675f9eb7ae2SShri Abhyankar    Collective on SNES
4676f9eb7ae2SShri Abhyankar 
4677f9eb7ae2SShri Abhyankar .seealso: SNESSetFunction(), SNESGetFunction()
4678f9eb7ae2SShri Abhyankar @*/
46797087cfbeSBarry Smith PetscErrorCode  SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
4680f9eb7ae2SShri Abhyankar {
4681f9eb7ae2SShri Abhyankar   PetscErrorCode  ierr;
468248f37e70SShri Abhyankar   SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
4683f9eb7ae2SShri Abhyankar   int             nlhs = 1,nrhs = 6;
4684f9eb7ae2SShri Abhyankar   mxArray	  *plhs[1],*prhs[6];
4685f9eb7ae2SShri Abhyankar   long long int   lx = 0,ls = 0;
4686f9eb7ae2SShri Abhyankar   Vec             x=snes->vec_sol;
4687f9eb7ae2SShri Abhyankar 
4688f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4689f9eb7ae2SShri Abhyankar   PetscValidHeaderSpecific(snes,SNES_CLASSID,1);
4690f9eb7ae2SShri Abhyankar 
4691f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&ls,&snes,sizeof(snes));CHKERRQ(ierr);
4692f9eb7ae2SShri Abhyankar   ierr = PetscMemcpy(&lx,&x,sizeof(x));CHKERRQ(ierr);
4693f9eb7ae2SShri Abhyankar   prhs[0] =  mxCreateDoubleScalar((double)ls);
4694f9eb7ae2SShri Abhyankar   prhs[1] =  mxCreateDoubleScalar((double)it);
4695f9eb7ae2SShri Abhyankar   prhs[2] =  mxCreateDoubleScalar((double)fnorm);
4696f9eb7ae2SShri Abhyankar   prhs[3] =  mxCreateDoubleScalar((double)lx);
4697f9eb7ae2SShri Abhyankar   prhs[4] =  mxCreateString(sctx->funcname);
4698f9eb7ae2SShri Abhyankar   prhs[5] =  sctx->ctx;
4699f9eb7ae2SShri Abhyankar   ierr    =  mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");CHKERRQ(ierr);
4700f9eb7ae2SShri Abhyankar   ierr    =  mxGetScalar(plhs[0]);CHKERRQ(ierr);
4701f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[0]);
4702f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[1]);
4703f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[2]);
4704f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[3]);
4705f9eb7ae2SShri Abhyankar   mxDestroyArray(prhs[4]);
4706f9eb7ae2SShri Abhyankar   mxDestroyArray(plhs[0]);
4707f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4708f9eb7ae2SShri Abhyankar }
4709f9eb7ae2SShri Abhyankar 
4710f9eb7ae2SShri Abhyankar 
4711f9eb7ae2SShri Abhyankar #undef __FUNCT__
4712f9eb7ae2SShri Abhyankar #define __FUNCT__ "SNESMonitorSetMatlab"
4713f9eb7ae2SShri Abhyankar /*
4714e3c5b3baSBarry Smith    SNESMonitorSetMatlab - Sets the monitor function from MATLAB
4715f9eb7ae2SShri Abhyankar 
4716f9eb7ae2SShri Abhyankar    Level: developer
4717f9eb7ae2SShri Abhyankar 
4718f9eb7ae2SShri Abhyankar .keywords: SNES, nonlinear, set, function
4719f9eb7ae2SShri Abhyankar 
4720f9eb7ae2SShri Abhyankar .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
4721f9eb7ae2SShri Abhyankar */
47227087cfbeSBarry Smith PetscErrorCode  SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
4723f9eb7ae2SShri Abhyankar {
4724f9eb7ae2SShri Abhyankar   PetscErrorCode    ierr;
4725f9eb7ae2SShri Abhyankar   SNESMatlabContext *sctx;
4726f9eb7ae2SShri Abhyankar 
4727f9eb7ae2SShri Abhyankar   PetscFunctionBegin;
4728f9eb7ae2SShri Abhyankar   /* currently sctx is memory bleed */
4729f9eb7ae2SShri Abhyankar   ierr = PetscMalloc(sizeof(SNESMatlabContext),&sctx);CHKERRQ(ierr);
4730f9eb7ae2SShri Abhyankar   ierr = PetscStrallocpy(func,&sctx->funcname);CHKERRQ(ierr);
4731f9eb7ae2SShri Abhyankar   /*
4732f9eb7ae2SShri Abhyankar      This should work, but it doesn't
4733f9eb7ae2SShri Abhyankar   sctx->ctx = ctx;
4734f9eb7ae2SShri Abhyankar   mexMakeArrayPersistent(sctx->ctx);
4735f9eb7ae2SShri Abhyankar   */
4736f9eb7ae2SShri Abhyankar   sctx->ctx = mxDuplicateArray(ctx);
4737f9eb7ae2SShri Abhyankar   ierr = SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);CHKERRQ(ierr);
4738f9eb7ae2SShri Abhyankar   PetscFunctionReturn(0);
4739f9eb7ae2SShri Abhyankar }
4740f9eb7ae2SShri Abhyankar 
474169b4f73cSBarry Smith #endif
4742