Actual source code: snes.c
2: #include <private/snesimpl.h> /*I "petscsnes.h" I*/
4: PetscBool SNESRegisterAllCalled = PETSC_FALSE;
5: PetscFList SNESList = PETSC_NULL;
7: /* Logging support */
8: PetscClassId SNES_CLASSID;
9: PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
13: /*
14: Translates from a SNES call to a DM call in computing a Jacobian
15: */
16: PetscErrorCode SNESDMComputeJacobian(SNES snes,Vec X,Mat *J,Mat *B,MatStructure *flag,void *ptr)
17: {
19: DM dm;
22: SNESGetDM(snes,&dm);
23: DMComputeJacobian(dm,X,*J,*B,flag);
24: return(0);
25: }
29: /*@
30: SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged.
32: Logically Collective on SNES
34: Input Parameters:
35: + snes - iterative context obtained from SNESCreate()
36: - flg - PETSC_TRUE indicates you want the error generated
38: Options database keys:
39: . -snes_error_if_not_converged : this takes an optional truth value (0/1/no/yes/true/false)
41: Level: intermediate
43: Notes:
44: Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve()
45: to determine if it has converged.
47: .keywords: SNES, set, initial guess, nonzero
49: .seealso: SNESGetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
50: @*/
51: PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg)
52: {
56: snes->errorifnotconverged = flg;
57: return(0);
58: }
62: /*@
63: SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge?
65: Not Collective
67: Input Parameter:
68: . snes - iterative context obtained from SNESCreate()
70: Output Parameter:
71: . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE
73: Level: intermediate
75: .keywords: SNES, set, initial guess, nonzero
77: .seealso: SNESSetErrorIfNotConverged(), KSPGetErrorIfNotConverged(), KSPSetErrorIFNotConverged()
78: @*/
79: PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag)
80: {
84: *flag = snes->errorifnotconverged;
85: return(0);
86: }
90: /*@
91: SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
92: in the functions domain. For example, negative pressure.
94: Logically Collective on SNES
96: Input Parameters:
97: . SNES - the SNES context
99: Level: advanced
101: .keywords: SNES, view
103: .seealso: SNESCreate(), SNESSetFunction()
104: @*/
105: PetscErrorCode SNESSetFunctionDomainError(SNES snes)
106: {
109: snes->domainerror = PETSC_TRUE;
110: return(0);
111: }
115: /*@C
116: SNESView - Prints the SNES data structure.
118: Collective on SNES
120: Input Parameters:
121: + SNES - the SNES context
122: - viewer - visualization context
124: Options Database Key:
125: . -snes_view - Calls SNESView() at end of SNESSolve()
127: Notes:
128: The available visualization contexts include
129: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
130: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
131: output where only the first processor opens
132: the file. All other processors send their
133: data to the first processor to print.
135: The user can open an alternative visualization context with
136: PetscViewerASCIIOpen() - output to a specified file.
138: Level: beginner
140: .keywords: SNES, view
142: .seealso: PetscViewerASCIIOpen()
143: @*/
144: PetscErrorCode SNESView(SNES snes,PetscViewer viewer)
145: {
146: SNESKSPEW *kctx;
147: PetscErrorCode ierr;
148: KSP ksp;
149: PetscBool iascii,isstring;
153: if (!viewer) {
154: PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);
155: }
159: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
160: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);
161: if (iascii) {
162: PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer,"SNES Object");
163: if (snes->ops->view) {
164: PetscViewerASCIIPushTab(viewer);
165: (*snes->ops->view)(snes,viewer);
166: PetscViewerASCIIPopTab(viewer);
167: }
168: PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
169: PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n",
170: snes->rtol,snes->abstol,snes->xtol);
171: PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);
172: PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);
173: if (snes->ksp_ewconv) {
174: kctx = (SNESKSPEW *)snes->kspconvctx;
175: if (kctx) {
176: PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
177: PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
178: PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
179: }
180: }
181: if (snes->lagpreconditioner == -1) {
182: PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n");
183: } else if (snes->lagpreconditioner > 1) {
184: PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %D new Jacobians\n",snes->lagpreconditioner);
185: }
186: if (snes->lagjacobian == -1) {
187: PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n");
188: } else if (snes->lagjacobian > 1) {
189: PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %D Newton iterations\n",snes->lagjacobian);
190: }
191: } else if (isstring) {
192: const char *type;
193: SNESGetType(snes,&type);
194: PetscViewerStringSPrintf(viewer," %-3.3s",type);
195: }
196: SNESGetKSP(snes,&ksp);
197: if (snes->pc) {
198: PetscViewerASCIIPushTab(viewer);
199: SNESView(snes->pc, viewer);
200: PetscViewerASCIIPopTab(viewer);
201: }
202: PetscViewerASCIIPushTab(viewer);
203: KSPView(ksp,viewer);
204: PetscViewerASCIIPopTab(viewer);
205: return(0);
206: }
208: /*
209: We retain a list of functions that also take SNES command
210: line options. These are called at the end SNESSetFromOptions()
211: */
212: #define MAXSETFROMOPTIONS 5
213: static PetscInt numberofsetfromoptions;
214: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
218: /*@C
219: SNESAddOptionsChecker - Adds an additional function to check for SNES options.
221: Not Collective
223: Input Parameter:
224: . snescheck - function that checks for options
226: Level: developer
228: .seealso: SNESSetFromOptions()
229: @*/
230: PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
231: {
233: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
234: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
235: }
236: othersetfromoptions[numberofsetfromoptions++] = snescheck;
237: return(0);
238: }
244: static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version)
245: {
246: Mat J;
247: KSP ksp;
248: PC pc;
249: PetscBool match;
255: if(!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) {
256: Mat A = snes->jacobian, B = snes->jacobian_pre;
257: MatGetVecs(A ? A : B, PETSC_NULL,&snes->vec_func);
258: }
260: if (version == 1) {
261: MatCreateSNESMF(snes,&J);
262: MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
263: MatSetFromOptions(J);
264: } else if (version == 2) {
265: if (!snes->vec_func) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first");
266: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL_LONG_DOUBLE)
267: SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J);
268: #else
269: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator rutines (version 2)");
270: #endif
271: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator rutines, only version 1 and 2");
272:
273: PetscInfo1(snes,"Setting default matrix-free operator routines (version %D)\n", version);
274: if (hasOperator) {
275: /* This version replaces the user provided Jacobian matrix with a
276: matrix-free version but still employs the user-provided preconditioner matrix. */
277: SNESSetJacobian(snes,J,0,0,0);
278: } else {
279: /* This version replaces both the user-provided Jacobian and the user-
280: provided preconditioner matrix with the default matrix free version. */
281: SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
282: /* Force no preconditioner */
283: SNESGetKSP(snes,&ksp);
284: KSPGetPC(ksp,&pc);
285: PetscTypeCompare((PetscObject)pc,PCSHELL,&match);
286: if (!match) {
287: PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n");
288: PCSetType(pc,PCNONE);
289: }
290: }
291: MatDestroy(&J);
292: return(0);
293: }
297: /*@
298: SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
300: Collective on SNES
302: Input Parameter:
303: . snes - the SNES context
305: Options Database Keys:
306: + -snes_type <type> - ls, tr, umls, umtr, test
307: . -snes_stol - convergence tolerance in terms of the norm
308: of the change in the solution between steps
309: . -snes_atol <abstol> - absolute tolerance of residual norm
310: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
311: . -snes_max_it <max_it> - maximum number of iterations
312: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
313: . -snes_max_fail <max_fail> - maximum number of failures
314: . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
315: . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
316: . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
317: . -snes_trtol <trtol> - trust region tolerance
318: . -snes_no_convergence_test - skip convergence test in nonlinear
319: solver; hence iterations will continue until max_it
320: or some other criterion is reached. Saves expense
321: of convergence test
322: . -snes_monitor <optional filename> - prints residual norm at each iteration. if no
323: filename given prints to stdout
324: . -snes_monitor_solution - plots solution at each iteration
325: . -snes_monitor_residual - plots residual (not its norm) at each iteration
326: . -snes_monitor_solution_update - plots update to solution at each iteration
327: . -snes_monitor_draw - plots residual norm at each iteration
328: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
329: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
330: - -snes_converged_reason - print the reason for convergence/divergence after each solve
332: Options Database for Eisenstat-Walker method:
333: + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
334: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
335: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
336: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
337: . -snes_ksp_ew_gamma <gamma> - Sets gamma
338: . -snes_ksp_ew_alpha <alpha> - Sets alpha
339: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
340: - -snes_ksp_ew_threshold <threshold> - Sets threshold
342: Notes:
343: To see all options, run your program with the -help option or consult
344: the <A href="../../docs/manual.pdf#nameddest=ch_snes">SNES chapter of the users manual</A>.
346: Level: beginner
348: .keywords: SNES, nonlinear, set, options, database
350: .seealso: SNESSetOptionsPrefix()
351: @*/
352: PetscErrorCode SNESSetFromOptions(SNES snes)
353: {
354: PetscBool flg,mf,mf_operator;
355: PetscInt i,indx,lag,mf_version,grids;
356: MatStructure matflag;
357: const char *deft = SNESLS;
358: const char *convtests[] = {"default","skip"};
359: SNESKSPEW *kctx = NULL;
360: char type[256], monfilename[PETSC_MAX_PATH_LEN];
361: PetscViewer monviewer;
362: PetscErrorCode ierr;
367: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
368: PetscObjectOptionsBegin((PetscObject)snes);
369: if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
370: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
371: if (flg) {
372: SNESSetType(snes,type);
373: } else if (!((PetscObject)snes)->type_name) {
374: SNESSetType(snes,deft);
375: }
376: /* not used here, but called so will go into help messaage */
377: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
379: PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->xtol,&snes->xtol,0);
380: PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,0);
382: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,0);
383: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
384: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
385: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
386: PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);
387: PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,PETSC_NULL);
389: PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
390: if (flg) {
391: SNESSetLagPreconditioner(snes,lag);
392: }
393: PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
394: if (flg) {
395: SNESSetLagJacobian(snes,lag);
396: }
397: PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg);
398: if (flg) {
399: SNESSetGridSequence(snes,grids);
400: }
402: PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
403: if (flg) {
404: switch (indx) {
405: case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL); break;
406: case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL); break;
407: }
408: }
410: PetscOptionsBool("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",snes->printreason,&snes->printreason,PETSC_NULL);
412: kctx = (SNESKSPEW *)snes->kspconvctx;
414: PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
416: PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
417: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
418: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
419: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
420: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
421: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
422: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);
424: flg = PETSC_FALSE;
425: PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,PETSC_NULL);
426: if (flg) {SNESMonitorCancel(snes);}
428: PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
429: if (flg) {
430: PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);
431: SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
432: }
434: PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
435: if (flg) {
436: SNESMonitorSet(snes,SNESMonitorRange,0,0);
437: }
439: PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
440: if (flg) {
441: PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);
442: SNESMonitorSetRatio(snes,monviewer);
443: }
445: PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
446: if (flg) {
447: PetscViewerASCIIOpen(((PetscObject)snes)->comm,monfilename,&monviewer);
448: SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
449: }
451: PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
452: if (flg) {PetscPythonMonitorSet((PetscObject)snes,monfilename);}
454: flg = PETSC_FALSE;
455: PetscOptionsBool("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",flg,&flg,PETSC_NULL);
456: if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
457: flg = PETSC_FALSE;
458: PetscOptionsBool("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",flg,&flg,PETSC_NULL);
459: if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
460: flg = PETSC_FALSE;
461: PetscOptionsBool("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",flg,&flg,PETSC_NULL);
462: if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
463: flg = PETSC_FALSE;
464: PetscOptionsBool("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);
465: if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
466: flg = PETSC_FALSE;
467: PetscOptionsBool("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",flg,&flg,PETSC_NULL);
468: if (flg) {SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);}
470: flg = PETSC_FALSE;
471: PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",flg,&flg,PETSC_NULL);
472: if (flg) {
473: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
474: PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
475: }
477: mf = mf_operator = PETSC_FALSE;
478: flg = PETSC_FALSE;
479: PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf_operator,&flg);
480: if (flg && mf_operator) {
481: snes->mf_operator = PETSC_TRUE;
482: mf = PETSC_TRUE;
483: }
484: flg = PETSC_FALSE;
485: PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","MatCreateSNESMF",PETSC_FALSE,&mf,&flg);
486: if (!flg && mf_operator) mf = PETSC_TRUE;
487: mf_version = 1;
488: PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",mf_version,&mf_version,0);
490: for(i = 0; i < numberofsetfromoptions; i++) {
491: (*othersetfromoptions[i])(snes);
492: }
494: if (snes->ops->setfromoptions) {
495: (*snes->ops->setfromoptions)(snes);
496: }
498: /* process any options handlers added with PetscObjectAddOptionsHandler() */
499: PetscObjectProcessOptionsHandlers((PetscObject)snes);
500: PetscOptionsEnd();
502: if (mf) { SNESSetUpMatrixFree_Private(snes, mf_operator, mf_version); }
504: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
505: KSPGetOperators(snes->ksp,PETSC_NULL,PETSC_NULL,&matflag);
506: KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,matflag);
507: KSPSetFromOptions(snes->ksp);
509: if (snes->pc) {
510: SNESSetOptionsPrefix(snes->pc, "npc_");
511: SNESSetDM(snes->pc, snes->dm);
512: /* Should we make a duplicate vector and matrix? Leave the DM to make it? */
513: SNESSetFunction(snes->pc, snes->vec_func, snes->ops->computefunction, snes->funP);
514: SNESSetJacobian(snes->pc, snes->jacobian, snes->jacobian_pre, snes->ops->computejacobian, snes->jacP);
515: SNESSetFromOptions(snes->pc);
516: }
517: return(0);
518: }
522: /*@
523: SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for
524: the nonlinear solvers.
526: Logically Collective on SNES
528: Input Parameters:
529: + snes - the SNES context
530: . compute - function to compute the context
531: - destroy - function to destroy the context
533: Level: intermediate
535: .keywords: SNES, nonlinear, set, application, context
537: .seealso: SNESGetApplicationContext(), SNESSetComputeApplicationContext(), SNESGetApplicationContext()
538: @*/
539: PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**))
540: {
543: snes->ops->usercompute = compute;
544: snes->ops->userdestroy = destroy;
545: return(0);
546: }
550: /*@
551: SNESSetApplicationContext - Sets the optional user-defined context for
552: the nonlinear solvers.
554: Logically Collective on SNES
556: Input Parameters:
557: + snes - the SNES context
558: - usrP - optional user context
560: Level: intermediate
562: .keywords: SNES, nonlinear, set, application, context
564: .seealso: SNESGetApplicationContext(), SNESSetApplicationContext()
565: @*/
566: PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP)
567: {
569: KSP ksp;
573: SNESGetKSP(snes,&ksp);
574: KSPSetApplicationContext(ksp,usrP);
575: snes->user = usrP;
576: return(0);
577: }
581: /*@
582: SNESGetApplicationContext - Gets the user-defined context for the
583: nonlinear solvers.
585: Not Collective
587: Input Parameter:
588: . snes - SNES context
590: Output Parameter:
591: . usrP - user context
593: Level: intermediate
595: .keywords: SNES, nonlinear, get, application, context
597: .seealso: SNESSetApplicationContext()
598: @*/
599: PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP)
600: {
603: *(void**)usrP = snes->user;
604: return(0);
605: }
609: /*@
610: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
611: at this time.
613: Not Collective
615: Input Parameter:
616: . snes - SNES context
618: Output Parameter:
619: . iter - iteration number
621: Notes:
622: For example, during the computation of iteration 2 this would return 1.
624: This is useful for using lagged Jacobians (where one does not recompute the
625: Jacobian at each SNES iteration). For example, the code
626: .vb
627: SNESGetIterationNumber(snes,&it);
628: if (!(it % 2)) {
629: [compute Jacobian here]
630: }
631: .ve
632: can be used in your ComputeJacobian() function to cause the Jacobian to be
633: recomputed every second SNES iteration.
635: Level: intermediate
637: .keywords: SNES, nonlinear, get, iteration, number,
639: .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
640: @*/
641: PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter)
642: {
646: *iter = snes->iter;
647: return(0);
648: }
652: /*@
653: SNESGetFunctionNorm - Gets the norm of the current function that was set
654: with SNESSSetFunction().
656: Collective on SNES
658: Input Parameter:
659: . snes - SNES context
661: Output Parameter:
662: . fnorm - 2-norm of function
664: Level: intermediate
666: .keywords: SNES, nonlinear, get, function, norm
668: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
669: @*/
670: PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
671: {
675: *fnorm = snes->norm;
676: return(0);
677: }
681: /*@
682: SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
683: attempted by the nonlinear solver.
685: Not Collective
687: Input Parameter:
688: . snes - SNES context
690: Output Parameter:
691: . nfails - number of unsuccessful steps attempted
693: Notes:
694: This counter is reset to zero for each successive call to SNESSolve().
696: Level: intermediate
698: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
700: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
701: SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
702: @*/
703: PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
704: {
708: *nfails = snes->numFailures;
709: return(0);
710: }
714: /*@
715: SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
716: attempted by the nonlinear solver before it gives up.
718: Not Collective
720: Input Parameters:
721: + snes - SNES context
722: - maxFails - maximum of unsuccessful steps
724: Level: intermediate
726: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
728: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
729: SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
730: @*/
731: PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
732: {
735: snes->maxFailures = maxFails;
736: return(0);
737: }
741: /*@
742: SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
743: attempted by the nonlinear solver before it gives up.
745: Not Collective
747: Input Parameter:
748: . snes - SNES context
750: Output Parameter:
751: . maxFails - maximum of unsuccessful steps
753: Level: intermediate
755: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
757: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
758: SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
759:
760: @*/
761: PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
762: {
766: *maxFails = snes->maxFailures;
767: return(0);
768: }
772: /*@
773: SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
774: done by SNES.
776: Not Collective
778: Input Parameter:
779: . snes - SNES context
781: Output Parameter:
782: . nfuncs - number of evaluations
784: Level: intermediate
786: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
788: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
789: @*/
790: PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
791: {
795: *nfuncs = snes->nfuncs;
796: return(0);
797: }
801: /*@
802: SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
803: linear solvers.
805: Not Collective
807: Input Parameter:
808: . snes - SNES context
810: Output Parameter:
811: . nfails - number of failed solves
813: Notes:
814: This counter is reset to zero for each successive call to SNESSolve().
816: Level: intermediate
818: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
820: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
821: @*/
822: PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
823: {
827: *nfails = snes->numLinearSolveFailures;
828: return(0);
829: }
833: /*@
834: SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
835: allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
837: Logically Collective on SNES
839: Input Parameters:
840: + snes - SNES context
841: - maxFails - maximum allowed linear solve failures
843: Level: intermediate
845: Notes: By default this is 0; that is SNES returns on the first failed linear solve
847: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
849: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
850: @*/
851: PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
852: {
856: snes->maxLinearSolveFailures = maxFails;
857: return(0);
858: }
862: /*@
863: SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
864: are allowed before SNES terminates
866: Not Collective
868: Input Parameter:
869: . snes - SNES context
871: Output Parameter:
872: . maxFails - maximum of unsuccessful solves allowed
874: Level: intermediate
876: Notes: By default this is 1; that is SNES returns on the first failed linear solve
878: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
880: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
881: @*/
882: PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
883: {
887: *maxFails = snes->maxLinearSolveFailures;
888: return(0);
889: }
893: /*@
894: SNESGetLinearSolveIterations - Gets the total number of linear iterations
895: used by the nonlinear solver.
897: Not Collective
899: Input Parameter:
900: . snes - SNES context
902: Output Parameter:
903: . lits - number of linear iterations
905: Notes:
906: This counter is reset to zero for each successive call to SNESSolve().
908: Level: intermediate
910: .keywords: SNES, nonlinear, get, number, linear, iterations
912: .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm(), SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
913: @*/
914: PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
915: {
919: *lits = snes->linear_its;
920: return(0);
921: }
925: /*@
926: SNESGetKSP - Returns the KSP context for a SNES solver.
928: Not Collective, but if SNES object is parallel, then KSP object is parallel
930: Input Parameter:
931: . snes - the SNES context
933: Output Parameter:
934: . ksp - the KSP context
936: Notes:
937: The user can then directly manipulate the KSP context to set various
938: options, etc. Likewise, the user can then extract and manipulate the
939: PC contexts as well.
941: Level: beginner
943: .keywords: SNES, nonlinear, get, KSP, context
945: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
946: @*/
947: PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp)
948: {
955: if (!snes->ksp) {
956: KSPCreate(((PetscObject)snes)->comm,&snes->ksp);
957: PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
958: PetscLogObjectParent(snes,snes->ksp);
959: }
960: *ksp = snes->ksp;
961: return(0);
962: }
966: /*@
967: SNESSetKSP - Sets a KSP context for the SNES object to use
969: Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
971: Input Parameters:
972: + snes - the SNES context
973: - ksp - the KSP context
975: Notes:
976: The SNES object already has its KSP object, you can obtain with SNESGetKSP()
977: so this routine is rarely needed.
979: The KSP object that is already in the SNES object has its reference count
980: decreased by one.
982: Level: developer
984: .keywords: SNES, nonlinear, get, KSP, context
986: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
987: @*/
988: PetscErrorCode SNESSetKSP(SNES snes,KSP ksp)
989: {
996: PetscObjectReference((PetscObject)ksp);
997: if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
998: snes->ksp = ksp;
999: return(0);
1000: }
1002: #if 0
1005: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
1006: {
1008: return(0);
1009: }
1010: #endif
1012: /* -----------------------------------------------------------*/
1015: /*@
1016: SNESCreate - Creates a nonlinear solver context.
1018: Collective on MPI_Comm
1020: Input Parameters:
1021: . comm - MPI communicator
1023: Output Parameter:
1024: . outsnes - the new SNES context
1026: Options Database Keys:
1027: + -snes_mf - Activates default matrix-free Jacobian-vector products,
1028: and no preconditioning matrix
1029: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
1030: products, and a user-provided preconditioning matrix
1031: as set by SNESSetJacobian()
1032: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
1034: Level: beginner
1036: .keywords: SNES, nonlinear, create, context
1038: .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
1040: @*/
1041: PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes)
1042: {
1043: PetscErrorCode ierr;
1044: SNES snes;
1045: SNESKSPEW *kctx;
1049: *outsnes = PETSC_NULL;
1050: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
1051: SNESInitializePackage(PETSC_NULL);
1052: #endif
1054: PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_CLASSID,0,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView);
1056: snes->ops->converged = SNESDefaultConverged;
1057: snes->max_its = 50;
1058: snes->max_funcs = 10000;
1059: snes->norm = 0.0;
1060: snes->rtol = 1.e-8;
1061: snes->ttol = 0.0;
1062: snes->abstol = 1.e-50;
1063: snes->xtol = 1.e-8;
1064: snes->deltatol = 1.e-12;
1065: snes->nfuncs = 0;
1066: snes->numFailures = 0;
1067: snes->maxFailures = 1;
1068: snes->linear_its = 0;
1069: snes->lagjacobian = 1;
1070: snes->lagpreconditioner = 1;
1071: snes->numbermonitors = 0;
1072: snes->data = 0;
1073: snes->setupcalled = PETSC_FALSE;
1074: snes->ksp_ewconv = PETSC_FALSE;
1075: snes->nwork = 0;
1076: snes->work = 0;
1077: snes->nvwork = 0;
1078: snes->vwork = 0;
1079: snes->conv_hist_len = 0;
1080: snes->conv_hist_max = 0;
1081: snes->conv_hist = PETSC_NULL;
1082: snes->conv_hist_its = PETSC_NULL;
1083: snes->conv_hist_reset = PETSC_TRUE;
1084: snes->reason = SNES_CONVERGED_ITERATING;
1086: snes->numLinearSolveFailures = 0;
1087: snes->maxLinearSolveFailures = 1;
1089: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
1090: PetscNewLog(snes,SNESKSPEW,&kctx);
1091: snes->kspconvctx = (void*)kctx;
1092: kctx->version = 2;
1093: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
1094: this was too large for some test cases */
1095: kctx->rtol_last = 0.0;
1096: kctx->rtol_max = .9;
1097: kctx->gamma = 1.0;
1098: kctx->alpha = .5*(1.0 + sqrt(5.0));
1099: kctx->alpha2 = kctx->alpha;
1100: kctx->threshold = .1;
1101: kctx->lresid_last = 0.0;
1102: kctx->norm_last = 0.0;
1104: *outsnes = snes;
1105: return(0);
1106: }
1110: /*@C
1111: SNESSetFunction - Sets the function evaluation routine and function
1112: vector for use by the SNES routines in solving systems of nonlinear
1113: equations.
1115: Logically Collective on SNES
1117: Input Parameters:
1118: + snes - the SNES context
1119: . r - vector to store function value
1120: . func - function evaluation routine
1121: - ctx - [optional] user-defined context for private data for the
1122: function evaluation routine (may be PETSC_NULL)
1124: Calling sequence of func:
1125: $ func (SNES snes,Vec x,Vec f,void *ctx);
1127: . f - function vector
1128: - ctx - optional user-defined function context
1130: Notes:
1131: The Newton-like methods typically solve linear systems of the form
1132: $ f'(x) x = -f(x),
1133: where f'(x) denotes the Jacobian matrix and f(x) is the function.
1135: Level: beginner
1137: .keywords: SNES, nonlinear, set, function
1139: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1140: @*/
1141: PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
1142: {
1146: if (r) {
1149: PetscObjectReference((PetscObject)r);
1150: VecDestroy(&snes->vec_func);
1151: snes->vec_func = r;
1152: } else if (!snes->vec_func && snes->dm) {
1153: DMCreateGlobalVector(snes->dm,&snes->vec_func);
1154: }
1155: if (func) snes->ops->computefunction = func;
1156: if (ctx) snes->funP = ctx;
1157: return(0);
1158: }
1162: /*@C
1163: SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem
1165: Logically Collective on SNES
1167: Input Parameters:
1168: + snes - the SNES context
1169: . func - function evaluation routine
1170: - ctx - [optional] user-defined context for private data for the
1171: function evaluation routine (may be PETSC_NULL)
1173: Calling sequence of func:
1174: $ func (SNES snes,Vec x,void *ctx);
1176: . f - function vector
1177: - ctx - optional user-defined function context
1179: Level: intermediate
1181: .keywords: SNES, nonlinear, set, function
1183: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
1184: @*/
1185: PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx)
1186: {
1189: if (func) snes->ops->computeinitialguess = func;
1190: if (ctx) snes->initialguessP = ctx;
1191: return(0);
1192: }
1194: /* --------------------------------------------------------------- */
1197: /*@C
1198: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
1199: it assumes a zero right hand side.
1201: Logically Collective on SNES
1203: Input Parameter:
1204: . snes - the SNES context
1206: Output Parameter:
1207: . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
1209: Level: intermediate
1211: .keywords: SNES, nonlinear, get, function, right hand side
1213: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
1214: @*/
1215: PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs)
1216: {
1220: *rhs = snes->vec_rhs;
1221: return(0);
1222: }
1226: /*@
1227: SNESComputeFunction - Calls the function that has been set with
1228: SNESSetFunction().
1230: Collective on SNES
1232: Input Parameters:
1233: + snes - the SNES context
1234: - x - input vector
1236: Output Parameter:
1237: . y - function vector, as set by SNESSetFunction()
1239: Notes:
1240: SNESComputeFunction() is typically used within nonlinear solvers
1241: implementations, so most users would not generally call this routine
1242: themselves.
1244: Level: developer
1246: .keywords: SNES, nonlinear, compute, function
1248: .seealso: SNESSetFunction(), SNESGetFunction()
1249: @*/
1250: PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y)
1251: {
1261: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
1262: if (snes->ops->computefunction) {
1263: PetscStackPush("SNES user function");
1264: (*snes->ops->computefunction)(snes,x,y,snes->funP);
1265: PetscStackPop;
1266: } else if (snes->vec_rhs) {
1267: MatMult(snes->jacobian, x, y);
1268: } else if (snes->dm) {
1269: DMComputeFunction(snes->dm,x,y);
1270: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve().");
1271: if (snes->vec_rhs) {
1272: VecAXPY(y,-1.0,snes->vec_rhs);
1273: }
1274: snes->nfuncs++;
1275: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
1276: return(0);
1277: }
1281: /*@
1282: SNESComputeJacobian - Computes the Jacobian matrix that has been
1283: set with SNESSetJacobian().
1285: Collective on SNES and Mat
1287: Input Parameters:
1288: + snes - the SNES context
1289: - x - input vector
1291: Output Parameters:
1292: + A - Jacobian matrix
1293: . B - optional preconditioning matrix
1294: - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1296: Options Database Keys:
1297: + -snes_lag_preconditioner <lag>
1298: . -snes_lag_jacobian <lag>
1299: . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences
1300: . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result
1301: . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result
1302: - -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix
1304: Notes:
1305: Most users should not need to explicitly call this routine, as it
1306: is used internally within the nonlinear solvers.
1308: See KSPSetOperators() for important information about setting the
1309: flag parameter.
1311: Level: developer
1313: .keywords: SNES, compute, Jacobian, matrix
1315: .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1316: @*/
1317: PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1318: {
1320: PetscBool flag;
1327: if (!snes->ops->computejacobian) return(0);
1329: /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1331: if (snes->lagjacobian == -2) {
1332: snes->lagjacobian = -1;
1333: PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
1334: } else if (snes->lagjacobian == -1) {
1335: *flg = SAME_PRECONDITIONER;
1336: PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
1337: PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1338: if (flag) {
1339: MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1340: MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1341: }
1342: return(0);
1343: } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1344: *flg = SAME_PRECONDITIONER;
1345: PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
1346: PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1347: if (flag) {
1348: MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1349: MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1350: }
1351: return(0);
1352: }
1354: *flg = DIFFERENT_NONZERO_PATTERN;
1355: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
1356: PetscStackPush("SNES user Jacobian function");
1357: (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1358: PetscStackPop;
1359: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
1361: if (snes->lagpreconditioner == -2) {
1362: PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");
1363: snes->lagpreconditioner = -1;
1364: } else if (snes->lagpreconditioner == -1) {
1365: *flg = SAME_PRECONDITIONER;
1366: PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
1367: } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1368: *flg = SAME_PRECONDITIONER;
1369: PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
1370: }
1372: /* make sure user returned a correct Jacobian and preconditioner */
1375: {
1376: PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE;
1377: PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit",&flag,PETSC_NULL);
1378: PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",&flag_draw,PETSC_NULL);
1379: PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",&flag_contour,PETSC_NULL);
1380: PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_compare_operator",&flag_operator,PETSC_NULL);
1381: if (flag || flag_draw || flag_contour) {
1382: Mat Bexp_mine = PETSC_NULL,Bexp,FDexp;
1383: MatStructure mstruct;
1384: PetscViewer vdraw,vstdout;
1385: PetscBool flg;
1386: if (flag_operator) {
1387: MatComputeExplicitOperator(*A,&Bexp_mine);
1388: Bexp = Bexp_mine;
1389: } else {
1390: /* See if the preconditioning matrix can be viewed and added directly */
1391: PetscTypeCompareAny((PetscObject)*B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"");
1392: if (flg) Bexp = *B;
1393: else {
1394: /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */
1395: MatComputeExplicitOperator(*B,&Bexp_mine);
1396: Bexp = Bexp_mine;
1397: }
1398: }
1399: MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp);
1400: SNESDefaultComputeJacobian(snes,X,&FDexp,&FDexp,&mstruct,NULL);
1401: PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&vstdout);
1402: if (flag_draw || flag_contour) {
1403: PetscViewerDrawOpen(((PetscObject)snes)->comm,0,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw);
1404: if (flag_contour) {PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);}
1405: } else vdraw = PETSC_NULL;
1406: PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator?"Jacobian":"preconditioning Jacobian");
1407: if (flag) {MatView(Bexp,vstdout);}
1408: if (vdraw) {MatView(Bexp,vdraw);}
1409: PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n");
1410: if (flag) {MatView(FDexp,vstdout);}
1411: if (vdraw) {MatView(FDexp,vdraw);}
1412: MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN);
1413: PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n");
1414: if (flag) {MatView(FDexp,vstdout);}
1415: if (vdraw) { /* Always use contour for the difference */
1416: PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR);
1417: MatView(FDexp,vdraw);
1418: PetscViewerPopFormat(vdraw);
1419: }
1420: if (flag_contour) {PetscViewerPopFormat(vdraw);}
1421: PetscViewerDestroy(&vdraw);
1422: MatDestroy(&Bexp_mine);
1423: MatDestroy(&FDexp);
1424: }
1425: }
1426: return(0);
1427: }
1431: /*@C
1432: SNESSetJacobian - Sets the function to compute Jacobian as well as the
1433: location to store the matrix.
1435: Logically Collective on SNES and Mat
1437: Input Parameters:
1438: + snes - the SNES context
1439: . A - Jacobian matrix
1440: . B - preconditioner matrix (usually same as the Jacobian)
1441: . func - Jacobian evaluation routine (if PETSC_NULL then SNES retains any previously set value)
1442: - ctx - [optional] user-defined context for private data for the
1443: Jacobian evaluation routine (may be PETSC_NULL) (if PETSC_NULL then SNES retains any previously set value)
1445: Calling sequence of func:
1446: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
1448: + x - input vector
1449: . A - Jacobian matrix
1450: . B - preconditioner matrix, usually the same as A
1451: . flag - flag indicating information about the preconditioner matrix
1452: structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1453: - ctx - [optional] user-defined Jacobian context
1455: Notes:
1456: See KSPSetOperators() for important information about setting the flag
1457: output parameter in the routine func(). Be sure to read this information!
1459: The routine func() takes Mat * as the matrix arguments rather than Mat.
1460: This allows the Jacobian evaluation routine to replace A and/or B with a
1461: completely new new matrix structure (not just different matrix elements)
1462: when appropriate, for instance, if the nonzero structure is changing
1463: throughout the global iterations.
1465: If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
1466: each matrix.
1468: If using SNESDefaultComputeJacobianColor() to assemble a Jacobian, the ctx argument
1469: must be a MatFDColoring.
1471: Level: beginner
1473: .keywords: SNES, nonlinear, set, Jacobian, matrix
1475: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1476: @*/
1477: PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1478: {
1487: if (func) snes->ops->computejacobian = func;
1488: if (ctx) snes->jacP = ctx;
1489: if (A) {
1490: PetscObjectReference((PetscObject)A);
1491: MatDestroy(&snes->jacobian);
1492: snes->jacobian = A;
1493: }
1494: if (B) {
1495: PetscObjectReference((PetscObject)B);
1496: MatDestroy(&snes->jacobian_pre);
1497: snes->jacobian_pre = B;
1498: }
1499: return(0);
1500: }
1504: /*@C
1505: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1506: provided context for evaluating the Jacobian.
1508: Not Collective, but Mat object will be parallel if SNES object is
1510: Input Parameter:
1511: . snes - the nonlinear solver context
1513: Output Parameters:
1514: + A - location to stash Jacobian matrix (or PETSC_NULL)
1515: . B - location to stash preconditioner matrix (or PETSC_NULL)
1516: . func - location to put Jacobian function (or PETSC_NULL)
1517: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
1519: Level: advanced
1521: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1522: @*/
1523: PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1524: {
1527: if (A) *A = snes->jacobian;
1528: if (B) *B = snes->jacobian_pre;
1529: if (func) *func = snes->ops->computejacobian;
1530: if (ctx) *ctx = snes->jacP;
1531: return(0);
1532: }
1534: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1538: /*@
1539: SNESSetUp - Sets up the internal data structures for the later use
1540: of a nonlinear solver.
1542: Collective on SNES
1544: Input Parameters:
1545: . snes - the SNES context
1547: Notes:
1548: For basic use of the SNES solvers the user need not explicitly call
1549: SNESSetUp(), since these actions will automatically occur during
1550: the call to SNESSolve(). However, if one wishes to control this
1551: phase separately, SNESSetUp() should be called after SNESCreate()
1552: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1554: Level: advanced
1556: .keywords: SNES, nonlinear, setup
1558: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1559: @*/
1560: PetscErrorCode SNESSetUp(SNES snes)
1561: {
1566: if (snes->setupcalled) return(0);
1568: if (!((PetscObject)snes)->type_name) {
1569: SNESSetType(snes,SNESLS);
1570: }
1572: if (!snes->vec_func) {
1573: if (snes->vec_rhs) {
1574: VecDuplicate(snes->vec_rhs,&snes->vec_func);
1575: } else if (snes->vec_sol) {
1576: VecDuplicate(snes->vec_sol,&snes->vec_func);
1577: } else if (snes->dm) {
1578: DMCreateGlobalVector(snes->dm,&snes->vec_func);
1579: }
1580: }
1581: if (snes->vec_func == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1582: if (snes->vec_rhs == snes->vec_sol) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector");
1584: if (!snes->vec_sol_update /* && snes->vec_sol */) {
1585: VecDuplicate(snes->vec_sol,&snes->vec_sol_update);
1586: PetscLogObjectParent(snes,snes->vec_sol_update);
1587: }
1589: if (!snes->ops->computejacobian && snes->dm) {
1590: Mat J;
1591: DMGetMatrix(snes->dm,MATAIJ,&J);
1592: SNESSetJacobian(snes,J,J,SNESDMComputeJacobian,PETSC_NULL);
1593: MatDestroy(&J);
1594: } else if (!snes->jacobian && snes->ops->computejacobian == MatMFFDComputeJacobian) {
1595: Mat J;
1596: MatCreateSNESMF(snes,&J);
1597: MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
1598: MatSetFromOptions(J);
1599: SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1600: MatDestroy(&J);
1601: } else if (snes->dm && snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) {
1602: Mat J,B;
1603: MatCreateSNESMF(snes,&J);
1604: MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix);
1605: MatSetFromOptions(J);
1606: DMGetMatrix(snes->dm,MATAIJ,&B);
1607: SNESSetJacobian(snes,J,B,SNESDMComputeJacobian,snes->funP);
1608: MatDestroy(&J);
1609: MatDestroy(&B);
1610: } else if (snes->dm && !snes->jacobian_pre){
1611: Mat J;
1612: DMGetMatrix(snes->dm,MATAIJ,&J);
1613: SNESSetJacobian(snes,J,J,PETSC_NULL,PETSC_NULL);
1614: MatDestroy(&J);
1615: }
1616: if (!snes->ops->computefunction && !snes->dm) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a residual function with SNESSetFunction() or call SNESSetDM()");
1617: if (!snes->vec_func) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_ARG_WRONGSTATE,"Must provide a vector when calling SNESSetFunction() or call SNESSetDM()");
1619: if (!snes->ksp) {SNESGetKSP(snes, &snes->ksp);}
1621: if (snes->ops->usercompute && !snes->user) {
1622: (*snes->ops->usercompute)(snes,(void**)&snes->user);
1623: }
1625: if (snes->ops->setup) {
1626: (*snes->ops->setup)(snes);
1627: }
1629: snes->setupcalled = PETSC_TRUE;
1630: return(0);
1631: }
1635: /*@
1636: SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats
1638: Collective on SNES
1640: Input Parameter:
1641: . snes - iterative context obtained from SNESCreate()
1643: Level: intermediate
1645: Notes: Also calls the application context destroy routine set with SNESSetComputeApplicationContext()
1647: .keywords: SNES, destroy
1649: .seealso: SNESCreate(), SNESSetUp(), SNESSolve()
1650: @*/
1651: PetscErrorCode SNESReset(SNES snes)
1652: {
1657: if (snes->ops->userdestroy && snes->user) {
1658: (*snes->ops->userdestroy)((void**)&snes->user);
1659: snes->user = PETSC_NULL;
1660: }
1661: if (snes->ops->reset) {
1662: (*snes->ops->reset)(snes);
1663: }
1664: if (snes->ksp) {KSPReset(snes->ksp);}
1665: VecDestroy(&snes->vec_rhs);
1666: VecDestroy(&snes->vec_sol);
1667: VecDestroy(&snes->vec_sol_update);
1668: VecDestroy(&snes->vec_func);
1669: MatDestroy(&snes->jacobian);
1670: MatDestroy(&snes->jacobian_pre);
1671: if (snes->work) {VecDestroyVecs(snes->nwork,&snes->work);}
1672: if (snes->vwork) {VecDestroyVecs(snes->nvwork,&snes->vwork);}
1673: snes->nwork = snes->nvwork = 0;
1674: snes->setupcalled = PETSC_FALSE;
1675: return(0);
1676: }
1680: /*@
1681: SNESDestroy - Destroys the nonlinear solver context that was created
1682: with SNESCreate().
1684: Collective on SNES
1686: Input Parameter:
1687: . snes - the SNES context
1689: Level: beginner
1691: .keywords: SNES, nonlinear, destroy
1693: .seealso: SNESCreate(), SNESSolve()
1694: @*/
1695: PetscErrorCode SNESDestroy(SNES *snes)
1696: {
1700: if (!*snes) return(0);
1702: if (--((PetscObject)(*snes))->refct > 0) {*snes = 0; return(0);}
1704: SNESReset((*snes));
1706: /* if memory was published with AMS then destroy it */
1707: PetscObjectDepublish((*snes));
1708: if ((*snes)->ops->destroy) {(*((*snes))->ops->destroy)((*snes));}
1710: DMDestroy(&(*snes)->dm);
1711: KSPDestroy(&(*snes)->ksp);
1713: PetscFree((*snes)->kspconvctx);
1714: if ((*snes)->ops->convergeddestroy) {
1715: (*(*snes)->ops->convergeddestroy)((*snes)->cnvP);
1716: }
1717: if ((*snes)->conv_malloc) {
1718: PetscFree((*snes)->conv_hist);
1719: PetscFree((*snes)->conv_hist_its);
1720: }
1721: SNESMonitorCancel((*snes));
1722: PetscHeaderDestroy(snes);
1723: return(0);
1724: }
1726: /* ----------- Routines to set solver parameters ---------- */
1730: /*@
1731: SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1733: Logically Collective on SNES
1735: Input Parameters:
1736: + snes - the SNES context
1737: - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1738: the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1740: Options Database Keys:
1741: . -snes_lag_preconditioner <lag>
1743: Notes:
1744: The default is 1
1745: The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1746: If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1748: Level: intermediate
1750: .keywords: SNES, nonlinear, set, convergence, tolerances
1752: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1754: @*/
1755: PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1756: {
1759: if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1760: if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1762: snes->lagpreconditioner = lag;
1763: return(0);
1764: }
1768: /*@
1769: SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does
1771: Logically Collective on SNES
1773: Input Parameters:
1774: + snes - the SNES context
1775: - steps - the number of refinements to do, defaults to 0
1777: Options Database Keys:
1778: . -snes_grid_sequence <steps>
1780: Level: intermediate
1782: .keywords: SNES, nonlinear, set, convergence, tolerances
1784: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1786: @*/
1787: PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps)
1788: {
1792: snes->gridsequence = steps;
1793: return(0);
1794: }
1798: /*@
1799: SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1801: Not Collective
1803: Input Parameter:
1804: . snes - the SNES context
1805:
1806: Output Parameter:
1807: . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1808: the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1810: Options Database Keys:
1811: . -snes_lag_preconditioner <lag>
1813: Notes:
1814: The default is 1
1815: The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1817: Level: intermediate
1819: .keywords: SNES, nonlinear, set, convergence, tolerances
1821: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1823: @*/
1824: PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1825: {
1828: *lag = snes->lagpreconditioner;
1829: return(0);
1830: }
1834: /*@
1835: SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1836: often the preconditioner is rebuilt.
1838: Logically Collective on SNES
1840: Input Parameters:
1841: + snes - the SNES context
1842: - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1843: the Jacobian is built etc. -2 means rebuild at next chance but then never again
1845: Options Database Keys:
1846: . -snes_lag_jacobian <lag>
1848: Notes:
1849: The default is 1
1850: The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1851: 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
1852: at the next Newton step but never again (unless it is reset to another value)
1854: Level: intermediate
1856: .keywords: SNES, nonlinear, set, convergence, tolerances
1858: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1860: @*/
1861: PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag)
1862: {
1865: if (lag < -2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1866: if (!lag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1868: snes->lagjacobian = lag;
1869: return(0);
1870: }
1874: /*@
1875: SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1877: Not Collective
1879: Input Parameter:
1880: . snes - the SNES context
1881:
1882: Output Parameter:
1883: . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1884: the Jacobian is built etc.
1886: Options Database Keys:
1887: . -snes_lag_jacobian <lag>
1889: Notes:
1890: The default is 1
1891: The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1893: Level: intermediate
1895: .keywords: SNES, nonlinear, set, convergence, tolerances
1897: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1899: @*/
1900: PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag)
1901: {
1904: *lag = snes->lagjacobian;
1905: return(0);
1906: }
1910: /*@
1911: SNESSetTolerances - Sets various parameters used in convergence tests.
1913: Logically Collective on SNES
1915: Input Parameters:
1916: + snes - the SNES context
1917: . abstol - absolute convergence tolerance
1918: . rtol - relative convergence tolerance
1919: . stol - convergence tolerance in terms of the norm
1920: of the change in the solution between steps
1921: . maxit - maximum number of iterations
1922: - maxf - maximum number of function evaluations
1924: Options Database Keys:
1925: + -snes_atol <abstol> - Sets abstol
1926: . -snes_rtol <rtol> - Sets rtol
1927: . -snes_stol <stol> - Sets stol
1928: . -snes_max_it <maxit> - Sets maxit
1929: - -snes_max_funcs <maxf> - Sets maxf
1931: Notes:
1932: The default maximum number of iterations is 50.
1933: The default maximum number of function evaluations is 1000.
1935: Level: intermediate
1937: .keywords: SNES, nonlinear, set, convergence, tolerances
1939: .seealso: SNESSetTrustRegionTolerance()
1940: @*/
1941: PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1942: {
1951: if (abstol != PETSC_DEFAULT) {
1952: if (abstol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %G must be non-negative",abstol);
1953: snes->abstol = abstol;
1954: }
1955: if (rtol != PETSC_DEFAULT) {
1956: 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);
1957: snes->rtol = rtol;
1958: }
1959: if (stol != PETSC_DEFAULT) {
1960: if (stol < 0.0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %G must be non-negative",stol);
1961: snes->xtol = stol;
1962: }
1963: if (maxit != PETSC_DEFAULT) {
1964: if (maxit < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %D must be non-negative",maxit);
1965: snes->max_its = maxit;
1966: }
1967: if (maxf != PETSC_DEFAULT) {
1968: if (maxf < 0) SETERRQ1(((PetscObject)snes)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %D must be non-negative",maxf);
1969: snes->max_funcs = maxf;
1970: }
1971: return(0);
1972: }
1976: /*@
1977: SNESGetTolerances - Gets various parameters used in convergence tests.
1979: Not Collective
1981: Input Parameters:
1982: + snes - the SNES context
1983: . atol - absolute convergence tolerance
1984: . rtol - relative convergence tolerance
1985: . stol - convergence tolerance in terms of the norm
1986: of the change in the solution between steps
1987: . maxit - maximum number of iterations
1988: - maxf - maximum number of function evaluations
1990: Notes:
1991: The user can specify PETSC_NULL for any parameter that is not needed.
1993: Level: intermediate
1995: .keywords: SNES, nonlinear, get, convergence, tolerances
1997: .seealso: SNESSetTolerances()
1998: @*/
1999: PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
2000: {
2003: if (atol) *atol = snes->abstol;
2004: if (rtol) *rtol = snes->rtol;
2005: if (stol) *stol = snes->xtol;
2006: if (maxit) *maxit = snes->max_its;
2007: if (maxf) *maxf = snes->max_funcs;
2008: return(0);
2009: }
2013: /*@
2014: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
2016: Logically Collective on SNES
2018: Input Parameters:
2019: + snes - the SNES context
2020: - tol - tolerance
2021:
2022: Options Database Key:
2023: . -snes_trtol <tol> - Sets tol
2025: Level: intermediate
2027: .keywords: SNES, nonlinear, set, trust region, tolerance
2029: .seealso: SNESSetTolerances()
2030: @*/
2031: PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
2032: {
2036: snes->deltatol = tol;
2037: return(0);
2038: }
2040: /*
2041: Duplicate the lg monitors for SNES from KSP; for some reason with
2042: dynamic libraries things don't work under Sun4 if we just use
2043: macros instead of functions
2044: */
2047: PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
2048: {
2053: KSPMonitorLG((KSP)snes,it,norm,ctx);
2054: return(0);
2055: }
2059: PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2060: {
2064: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
2065: return(0);
2066: }
2070: PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG *draw)
2071: {
2075: KSPMonitorLGDestroy(draw);
2076: return(0);
2077: }
2082: PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
2083: {
2084: PetscDrawLG lg;
2085: PetscErrorCode ierr;
2086: PetscReal x,y,per;
2087: PetscViewer v = (PetscViewer)monctx;
2088: static PetscReal prev; /* should be in the context */
2089: PetscDraw draw;
2091: if (!monctx) {
2092: MPI_Comm comm;
2094: PetscObjectGetComm((PetscObject)snes,&comm);
2095: v = PETSC_VIEWER_DRAW_(comm);
2096: }
2097: PetscViewerDrawGetDrawLG(v,0,&lg);
2098: if (!n) {PetscDrawLGReset(lg);}
2099: PetscDrawLGGetDraw(lg,&draw);
2100: PetscDrawSetTitle(draw,"Residual norm");
2101: x = (PetscReal) n;
2102: if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
2103: PetscDrawLGAddPoint(lg,&x,&y);
2104: if (n < 20 || !(n % 5)) {
2105: PetscDrawLGDraw(lg);
2106: }
2108: PetscViewerDrawGetDrawLG(v,1,&lg);
2109: if (!n) {PetscDrawLGReset(lg);}
2110: PetscDrawLGGetDraw(lg,&draw);
2111: PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
2112: SNESMonitorRange_Private(snes,n,&per);
2113: x = (PetscReal) n;
2114: y = 100.0*per;
2115: PetscDrawLGAddPoint(lg,&x,&y);
2116: if (n < 20 || !(n % 5)) {
2117: PetscDrawLGDraw(lg);
2118: }
2120: PetscViewerDrawGetDrawLG(v,2,&lg);
2121: if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
2122: PetscDrawLGGetDraw(lg,&draw);
2123: PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
2124: x = (PetscReal) n;
2125: y = (prev - rnorm)/prev;
2126: PetscDrawLGAddPoint(lg,&x,&y);
2127: if (n < 20 || !(n % 5)) {
2128: PetscDrawLGDraw(lg);
2129: }
2131: PetscViewerDrawGetDrawLG(v,3,&lg);
2132: if (!n) {PetscDrawLGReset(lg);}
2133: PetscDrawLGGetDraw(lg,&draw);
2134: PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
2135: x = (PetscReal) n;
2136: y = (prev - rnorm)/(prev*per);
2137: if (n > 2) { /*skip initial crazy value */
2138: PetscDrawLGAddPoint(lg,&x,&y);
2139: }
2140: if (n < 20 || !(n % 5)) {
2141: PetscDrawLGDraw(lg);
2142: }
2143: prev = rnorm;
2144: return(0);
2145: }
2149: PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
2150: {
2154: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
2155: return(0);
2156: }
2160: PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG *draw)
2161: {
2165: KSPMonitorLGDestroy(draw);
2166: return(0);
2167: }
2171: /*@
2172: SNESMonitor - runs the user provided monitor routines, if they exist
2174: Collective on SNES
2176: Input Parameters:
2177: + snes - nonlinear solver context obtained from SNESCreate()
2178: . iter - iteration number
2179: - rnorm - relative norm of the residual
2181: Notes:
2182: This routine is called by the SNES implementations.
2183: It does not typically need to be called by the user.
2185: Level: developer
2187: .seealso: SNESMonitorSet()
2188: @*/
2189: PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm)
2190: {
2192: PetscInt i,n = snes->numbermonitors;
2195: for (i=0; i<n; i++) {
2196: (*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i]);
2197: }
2198: return(0);
2199: }
2201: /* ------------ Routines to set performance monitoring options ----------- */
2205: /*@C
2206: SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
2207: iteration of the nonlinear solver to display the iteration's
2208: progress.
2210: Logically Collective on SNES
2212: Input Parameters:
2213: + snes - the SNES context
2214: . func - monitoring routine
2215: . mctx - [optional] user-defined context for private data for the
2216: monitor routine (use PETSC_NULL if no context is desired)
2217: - monitordestroy - [optional] routine that frees monitor context
2218: (may be PETSC_NULL)
2220: Calling sequence of func:
2221: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
2223: + snes - the SNES context
2224: . its - iteration number
2225: . norm - 2-norm function value (may be estimated)
2226: - mctx - [optional] monitoring context
2228: Options Database Keys:
2229: + -snes_monitor - sets SNESMonitorDefault()
2230: . -snes_monitor_draw - sets line graph monitor,
2231: uses SNESMonitorLGCreate()
2232: - -snes_monitor_cancel - cancels all monitors that have
2233: been hardwired into a code by
2234: calls to SNESMonitorSet(), but
2235: does not cancel those set via
2236: the options database.
2238: Notes:
2239: Several different monitoring routines may be set by calling
2240: SNESMonitorSet() multiple times; all will be called in the
2241: order in which they were set.
2243: Fortran notes: Only a single monitor function can be set for each SNES object
2245: Level: intermediate
2247: .keywords: SNES, nonlinear, set, monitor
2249: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
2250: @*/
2251: PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**))
2252: {
2253: PetscInt i;
2258: if (snes->numbermonitors >= MAXSNESMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
2259: for (i=0; i<snes->numbermonitors;i++) {
2260: if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) {
2261: if (monitordestroy) {
2262: (*monitordestroy)(&mctx);
2263: }
2264: return(0);
2265: }
2266: }
2267: snes->monitor[snes->numbermonitors] = monitor;
2268: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
2269: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
2270: return(0);
2271: }
2275: /*@C
2276: SNESMonitorCancel - Clears all the monitor functions for a SNES object.
2278: Logically Collective on SNES
2280: Input Parameters:
2281: . snes - the SNES context
2283: Options Database Key:
2284: . -snes_monitor_cancel - cancels all monitors that have been hardwired
2285: into a code by calls to SNESMonitorSet(), but does not cancel those
2286: set via the options database
2288: Notes:
2289: There is no way to clear one specific monitor from a SNES object.
2291: Level: intermediate
2293: .keywords: SNES, nonlinear, set, monitor
2295: .seealso: SNESMonitorDefault(), SNESMonitorSet()
2296: @*/
2297: PetscErrorCode SNESMonitorCancel(SNES snes)
2298: {
2300: PetscInt i;
2304: for (i=0; i<snes->numbermonitors; i++) {
2305: if (snes->monitordestroy[i]) {
2306: (*snes->monitordestroy[i])(&snes->monitorcontext[i]);
2307: }
2308: }
2309: snes->numbermonitors = 0;
2310: return(0);
2311: }
2315: /*@C
2316: SNESSetConvergenceTest - Sets the function that is to be used
2317: to test for convergence of the nonlinear iterative solution.
2319: Logically Collective on SNES
2321: Input Parameters:
2322: + snes - the SNES context
2323: . func - routine to test for convergence
2324: . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL)
2325: - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
2327: Calling sequence of func:
2328: $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
2330: + snes - the SNES context
2331: . it - current iteration (0 is the first and is before any Newton step)
2332: . cctx - [optional] convergence context
2333: . reason - reason for convergence/divergence
2334: . xnorm - 2-norm of current iterate
2335: . gnorm - 2-norm of current step
2336: - f - 2-norm of function
2338: Level: advanced
2340: .keywords: SNES, nonlinear, set, convergence, test
2342: .seealso: SNESDefaultConverged(), SNESSkipConverged()
2343: @*/
2344: PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
2345: {
2350: if (!func) func = SNESSkipConverged;
2351: if (snes->ops->convergeddestroy) {
2352: (*snes->ops->convergeddestroy)(snes->cnvP);
2353: }
2354: snes->ops->converged = func;
2355: snes->ops->convergeddestroy = destroy;
2356: snes->cnvP = cctx;
2357: return(0);
2358: }
2362: /*@
2363: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
2365: Not Collective
2367: Input Parameter:
2368: . snes - the SNES context
2370: Output Parameter:
2371: . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
2372: manual pages for the individual convergence tests for complete lists
2374: Level: intermediate
2376: Notes: Can only be called after the call the SNESSolve() is complete.
2378: .keywords: SNES, nonlinear, set, convergence, test
2380: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
2381: @*/
2382: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
2383: {
2387: *reason = snes->reason;
2388: return(0);
2389: }
2393: /*@
2394: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
2396: Logically Collective on SNES
2398: Input Parameters:
2399: + snes - iterative context obtained from SNESCreate()
2400: . a - array to hold history, this array will contain the function norms computed at each step
2401: . its - integer array holds the number of linear iterations for each solve.
2402: . na - size of a and its
2403: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
2404: else it continues storing new values for new nonlinear solves after the old ones
2406: Notes:
2407: If 'a' and 'its' are PETSC_NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a
2408: default array of length 10000 is allocated.
2410: This routine is useful, e.g., when running a code for purposes
2411: of accurate performance monitoring, when no I/O should be done
2412: during the section of code that is being timed.
2414: Level: intermediate
2416: .keywords: SNES, set, convergence, history
2418: .seealso: SNESGetConvergenceHistory()
2420: @*/
2421: PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset)
2422: {
2429: if (na == PETSC_DECIDE || na == PETSC_DEFAULT || !a) {
2430: if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000;
2431: PetscMalloc(na*sizeof(PetscReal),&a);
2432: PetscMalloc(na*sizeof(PetscInt),&its);
2433: snes->conv_malloc = PETSC_TRUE;
2434: }
2435: snes->conv_hist = a;
2436: snes->conv_hist_its = its;
2437: snes->conv_hist_max = na;
2438: snes->conv_hist_len = 0;
2439: snes->conv_hist_reset = reset;
2440: return(0);
2441: }
2443: #if defined(PETSC_HAVE_MATLAB_ENGINE)
2444: #include <engine.h> /* MATLAB include file */
2445: #include <mex.h> /* MATLAB include file */
2449: mxArray *SNESGetConvergenceHistoryMatlab(SNES snes)
2450: {
2451: mxArray *mat;
2452: PetscInt i;
2453: PetscReal *ar;
2456: mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL);
2457: ar = (PetscReal*) mxGetData(mat);
2458: for (i=0; i<snes->conv_hist_len; i++) {
2459: ar[i] = snes->conv_hist[i];
2460: }
2461: PetscFunctionReturn(mat);
2462: }
2464: #endif
2469: /*@C
2470: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2472: Not Collective
2474: Input Parameter:
2475: . snes - iterative context obtained from SNESCreate()
2477: Output Parameters:
2478: . a - array to hold history
2479: . its - integer array holds the number of linear iterations (or
2480: negative if not converged) for each solve.
2481: - na - size of a and its
2483: Notes:
2484: The calling sequence for this routine in Fortran is
2485: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2487: This routine is useful, e.g., when running a code for purposes
2488: of accurate performance monitoring, when no I/O should be done
2489: during the section of code that is being timed.
2491: Level: intermediate
2493: .keywords: SNES, get, convergence, history
2495: .seealso: SNESSetConvergencHistory()
2497: @*/
2498: PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2499: {
2502: if (a) *a = snes->conv_hist;
2503: if (its) *its = snes->conv_hist_its;
2504: if (na) *na = snes->conv_hist_len;
2505: return(0);
2506: }
2510: /*@C
2511: SNESSetUpdate - Sets the general-purpose update function called
2512: at the beginning of every iteration of the nonlinear solve. Specifically
2513: it is called just before the Jacobian is "evaluated".
2515: Logically Collective on SNES
2517: Input Parameters:
2518: . snes - The nonlinear solver context
2519: . func - The function
2521: Calling sequence of func:
2522: . func (SNES snes, PetscInt step);
2524: . step - The current step of the iteration
2526: Level: advanced
2528: 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()
2529: This is not used by most users.
2531: .keywords: SNES, update
2533: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
2534: @*/
2535: PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
2536: {
2539: snes->ops->update = func;
2540: return(0);
2541: }
2545: /*@
2546: SNESDefaultUpdate - The default update function which does nothing.
2548: Not collective
2550: Input Parameters:
2551: . snes - The nonlinear solver context
2552: . step - The current step of the iteration
2554: Level: intermediate
2556: .keywords: SNES, update
2557: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
2558: @*/
2559: PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step)
2560: {
2562: return(0);
2563: }
2567: /*
2568: SNESScaleStep_Private - Scales a step so that its length is less than the
2569: positive parameter delta.
2571: Input Parameters:
2572: + snes - the SNES context
2573: . y - approximate solution of linear system
2574: . fnorm - 2-norm of current function
2575: - delta - trust region size
2577: Output Parameters:
2578: + gpnorm - predicted function norm at the new point, assuming local
2579: linearization. The value is zero if the step lies within the trust
2580: region, and exceeds zero otherwise.
2581: - ynorm - 2-norm of the step
2583: Note:
2584: For non-trust region methods such as SNESLS, the parameter delta
2585: is set to be the maximum allowable step size.
2587: .keywords: SNES, nonlinear, scale, step
2588: */
2589: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
2590: {
2591: PetscReal nrm;
2592: PetscScalar cnorm;
2600: VecNorm(y,NORM_2,&nrm);
2601: if (nrm > *delta) {
2602: nrm = *delta/nrm;
2603: *gpnorm = (1.0 - nrm)*(*fnorm);
2604: cnorm = nrm;
2605: VecScale(y,cnorm);
2606: *ynorm = *delta;
2607: } else {
2608: *gpnorm = 0.0;
2609: *ynorm = nrm;
2610: }
2611: return(0);
2612: }
2616: /*@C
2617: SNESSolve - Solves a nonlinear system F(x) = b.
2618: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
2620: Collective on SNES
2622: Input Parameters:
2623: + snes - the SNES context
2624: . b - the constant part of the equation F(x) = b, or PETSC_NULL to use zero.
2625: - x - the solution vector.
2627: Notes:
2628: The user should initialize the vector,x, with the initial guess
2629: for the nonlinear solve prior to calling SNESSolve. In particular,
2630: to employ an initial guess of zero, the user should explicitly set
2631: this vector to zero by calling VecSet().
2633: Level: beginner
2635: .keywords: SNES, nonlinear, solve
2637: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
2638: @*/
2639: PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x)
2640: {
2642: PetscBool flg;
2643: char filename[PETSC_MAX_PATH_LEN];
2644: PetscViewer viewer;
2645: PetscInt grid;
2654: for (grid=0; grid<snes->gridsequence; grid++) {PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));}
2655: for (grid=0; grid<snes->gridsequence+1; grid++) {
2657: /* set solution vector */
2658: if (!grid) {PetscObjectReference((PetscObject)x);}
2659: VecDestroy(&snes->vec_sol);
2660: snes->vec_sol = x;
2661: /* set afine vector if provided */
2662: if (b) { PetscObjectReference((PetscObject)b); }
2663: VecDestroy(&snes->vec_rhs);
2664: snes->vec_rhs = b;
2666: SNESSetUp(snes);
2668: if (!grid && snes->ops->computeinitialguess) {
2669: (*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP);
2670: }
2672: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
2673: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2675: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
2676: (*snes->ops->solve)(snes);
2677: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
2678: if (snes->domainerror){
2679: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
2680: snes->domainerror = PETSC_FALSE;
2681: }
2682: if (!snes->reason) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
2684: PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
2685: if (flg && !PetscPreLoadingOn) {
2686: PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
2687: SNESView(snes,viewer);
2688: PetscViewerDestroy(&viewer);
2689: }
2690:
2691: flg = PETSC_FALSE;
2692: PetscOptionsGetBool(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg,PETSC_NULL);
2693: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
2694: if (snes->printreason) {
2695: PetscViewerASCIIAddTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);
2696: if (snes->reason > 0) {
2697: PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
2698: } else {
2699: PetscViewerASCIIPrintf(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
2700: }
2701: PetscViewerASCIISubtractTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm),((PetscObject)snes)->tablevel);
2702: }
2703:
2704: if (snes->errorifnotconverged && snes->reason < 0) SETERRQ(((PetscObject)snes)->comm,PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged");
2705: if (grid < snes->gridsequence) {
2706: DM fine;
2707: Vec xnew;
2708: Mat interp;
2710: DMRefine(snes->dm,((PetscObject)snes)->comm,&fine);
2711: DMGetInterpolation(snes->dm,fine,&interp,PETSC_NULL);
2712: DMCreateGlobalVector(fine,&xnew);
2713: MatInterpolate(interp,x,xnew);
2714: MatDestroy(&interp);
2715: x = xnew;
2717: SNESReset(snes);
2718: SNESSetDM(snes,fine);
2719: DMDestroy(&fine);
2720: PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(((PetscObject)snes)->comm));
2721: }
2722: }
2723: return(0);
2724: }
2726: /* --------- Internal routines for SNES Package --------- */
2730: /*@C
2731: SNESSetType - Sets the method for the nonlinear solver.
2733: Collective on SNES
2735: Input Parameters:
2736: + snes - the SNES context
2737: - type - a known method
2739: Options Database Key:
2740: . -snes_type <type> - Sets the method; use -help for a list
2741: of available methods (for instance, ls or tr)
2743: Notes:
2744: See "petsc/include/petscsnes.h" for available methods (for instance)
2745: + SNESLS - Newton's method with line search
2746: (systems of nonlinear equations)
2747: . SNESTR - Newton's method with trust region
2748: (systems of nonlinear equations)
2750: Normally, it is best to use the SNESSetFromOptions() command and then
2751: set the SNES solver type from the options database rather than by using
2752: this routine. Using the options database provides the user with
2753: maximum flexibility in evaluating the many nonlinear solvers.
2754: The SNESSetType() routine is provided for those situations where it
2755: is necessary to set the nonlinear solver independently of the command
2756: line or options database. This might be the case, for example, when
2757: the choice of solver changes during the execution of the program,
2758: and the user's application is taking responsibility for choosing the
2759: appropriate method.
2761: Level: intermediate
2763: .keywords: SNES, set, type
2765: .seealso: SNESType, SNESCreate()
2767: @*/
2768: PetscErrorCode SNESSetType(SNES snes,const SNESType type)
2769: {
2770: PetscErrorCode ierr,(*r)(SNES);
2771: PetscBool match;
2777: PetscTypeCompare((PetscObject)snes,type,&match);
2778: if (match) return(0);
2780: PetscFListFind(SNESList,((PetscObject)snes)->comm,type,PETSC_TRUE,(void (**)(void)) &r);
2781: if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
2782: /* Destroy the previous private SNES context */
2783: if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
2784: /* Reinitialize function pointers in SNESOps structure */
2785: snes->ops->setup = 0;
2786: snes->ops->solve = 0;
2787: snes->ops->view = 0;
2788: snes->ops->setfromoptions = 0;
2789: snes->ops->destroy = 0;
2790: /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
2791: snes->setupcalled = PETSC_FALSE;
2792: PetscObjectChangeTypeName((PetscObject)snes,type);
2793: (*r)(snes);
2794: #if defined(PETSC_HAVE_AMS)
2795: if (PetscAMSPublishAll) {
2796: PetscObjectAMSPublish((PetscObject)snes);
2797: }
2798: #endif
2799: return(0);
2800: }
2803: /* --------------------------------------------------------------------- */
2806: /*@
2807: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2808: registered by SNESRegisterDynamic().
2810: Not Collective
2812: Level: advanced
2814: .keywords: SNES, nonlinear, register, destroy
2816: .seealso: SNESRegisterAll(), SNESRegisterAll()
2817: @*/
2818: PetscErrorCode SNESRegisterDestroy(void)
2819: {
2823: PetscFListDestroy(&SNESList);
2824: SNESRegisterAllCalled = PETSC_FALSE;
2825: return(0);
2826: }
2830: /*@C
2831: SNESGetType - Gets the SNES method type and name (as a string).
2833: Not Collective
2835: Input Parameter:
2836: . snes - nonlinear solver context
2838: Output Parameter:
2839: . type - SNES method (a character string)
2841: Level: intermediate
2843: .keywords: SNES, nonlinear, get, type, name
2844: @*/
2845: PetscErrorCode SNESGetType(SNES snes,const SNESType *type)
2846: {
2850: *type = ((PetscObject)snes)->type_name;
2851: return(0);
2852: }
2856: /*@
2857: SNESGetSolution - Returns the vector where the approximate solution is
2858: stored.
2860: Not Collective, but Vec is parallel if SNES is parallel
2862: Input Parameter:
2863: . snes - the SNES context
2865: Output Parameter:
2866: . x - the solution
2868: Level: intermediate
2870: .keywords: SNES, nonlinear, get, solution
2872: .seealso: SNESGetSolutionUpdate(), SNESGetFunction()
2873: @*/
2874: PetscErrorCode SNESGetSolution(SNES snes,Vec *x)
2875: {
2879: *x = snes->vec_sol;
2880: return(0);
2881: }
2885: /*@
2886: SNESGetSolutionUpdate - Returns the vector where the solution update is
2887: stored.
2889: Not Collective, but Vec is parallel if SNES is parallel
2891: Input Parameter:
2892: . snes - the SNES context
2894: Output Parameter:
2895: . x - the solution update
2897: Level: advanced
2899: .keywords: SNES, nonlinear, get, solution, update
2901: .seealso: SNESGetSolution(), SNESGetFunction()
2902: @*/
2903: PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x)
2904: {
2908: *x = snes->vec_sol_update;
2909: return(0);
2910: }
2914: /*@C
2915: SNESGetFunction - Returns the vector where the function is stored.
2917: Not Collective, but Vec is parallel if SNES is parallel
2919: Input Parameter:
2920: . snes - the SNES context
2922: Output Parameter:
2923: + r - the function (or PETSC_NULL)
2924: . func - the function (or PETSC_NULL)
2925: - ctx - the function context (or PETSC_NULL)
2927: Level: advanced
2929: .keywords: SNES, nonlinear, get, function
2931: .seealso: SNESSetFunction(), SNESGetSolution()
2932: @*/
2933: PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2934: {
2937: if (r) *r = snes->vec_func;
2938: if (func) *func = snes->ops->computefunction;
2939: if (ctx) *ctx = snes->funP;
2940: return(0);
2941: }
2945: /*@C
2946: SNESSetOptionsPrefix - Sets the prefix used for searching for all
2947: SNES options in the database.
2949: Logically Collective on SNES
2951: Input Parameter:
2952: + snes - the SNES context
2953: - prefix - the prefix to prepend to all option names
2955: Notes:
2956: A hyphen (-) must NOT be given at the beginning of the prefix name.
2957: The first character of all runtime options is AUTOMATICALLY the hyphen.
2959: Level: advanced
2961: .keywords: SNES, set, options, prefix, database
2963: .seealso: SNESSetFromOptions()
2964: @*/
2965: PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[])
2966: {
2971: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2972: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2973: KSPSetOptionsPrefix(snes->ksp,prefix);
2974: return(0);
2975: }
2979: /*@C
2980: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2981: SNES options in the database.
2983: Logically Collective on SNES
2985: Input Parameters:
2986: + snes - the SNES context
2987: - prefix - the prefix to prepend to all option names
2989: Notes:
2990: A hyphen (-) must NOT be given at the beginning of the prefix name.
2991: The first character of all runtime options is AUTOMATICALLY the hyphen.
2993: Level: advanced
2995: .keywords: SNES, append, options, prefix, database
2997: .seealso: SNESGetOptionsPrefix()
2998: @*/
2999: PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[])
3000: {
3002:
3005: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
3006: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
3007: KSPAppendOptionsPrefix(snes->ksp,prefix);
3008: return(0);
3009: }
3013: /*@C
3014: SNESGetOptionsPrefix - Sets the prefix used for searching for all
3015: SNES options in the database.
3017: Not Collective
3019: Input Parameter:
3020: . snes - the SNES context
3022: Output Parameter:
3023: . prefix - pointer to the prefix string used
3025: Notes: On the fortran side, the user should pass in a string 'prefix' of
3026: sufficient length to hold the prefix.
3028: Level: advanced
3030: .keywords: SNES, get, options, prefix, database
3032: .seealso: SNESAppendOptionsPrefix()
3033: @*/
3034: PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[])
3035: {
3040: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
3041: return(0);
3042: }
3047: /*@C
3048: SNESRegister - See SNESRegisterDynamic()
3050: Level: advanced
3051: @*/
3052: PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
3053: {
3054: char fullname[PETSC_MAX_PATH_LEN];
3058: PetscFListConcat(path,name,fullname);
3059: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
3060: return(0);
3061: }
3065: PetscErrorCode SNESTestLocalMin(SNES snes)
3066: {
3068: PetscInt N,i,j;
3069: Vec u,uh,fh;
3070: PetscScalar value;
3071: PetscReal norm;
3074: SNESGetSolution(snes,&u);
3075: VecDuplicate(u,&uh);
3076: VecDuplicate(u,&fh);
3078: /* currently only works for sequential */
3079: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
3080: VecGetSize(u,&N);
3081: for (i=0; i<N; i++) {
3082: VecCopy(u,uh);
3083: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
3084: for (j=-10; j<11; j++) {
3085: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
3086: VecSetValue(uh,i,value,ADD_VALUES);
3087: SNESComputeFunction(snes,uh,fh);
3088: VecNorm(fh,NORM_2,&norm);
3089: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
3090: value = -value;
3091: VecSetValue(uh,i,value,ADD_VALUES);
3092: }
3093: }
3094: VecDestroy(&uh);
3095: VecDestroy(&fh);
3096: return(0);
3097: }
3101: /*@
3102: SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
3103: computing relative tolerance for linear solvers within an inexact
3104: Newton method.
3106: Logically Collective on SNES
3108: Input Parameters:
3109: + snes - SNES context
3110: - flag - PETSC_TRUE or PETSC_FALSE
3112: Options Database:
3113: + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
3114: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
3115: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
3116: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
3117: . -snes_ksp_ew_gamma <gamma> - Sets gamma
3118: . -snes_ksp_ew_alpha <alpha> - Sets alpha
3119: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
3120: - -snes_ksp_ew_threshold <threshold> - Sets threshold
3122: Notes:
3123: Currently, the default is to use a constant relative tolerance for
3124: the inner linear solvers. Alternatively, one can use the
3125: Eisenstat-Walker method, where the relative convergence tolerance
3126: is reset at each Newton iteration according progress of the nonlinear
3127: solver.
3129: Level: advanced
3131: Reference:
3132: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
3133: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
3135: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
3137: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
3138: @*/
3139: PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag)
3140: {
3144: snes->ksp_ewconv = flag;
3145: return(0);
3146: }
3150: /*@
3151: SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
3152: for computing relative tolerance for linear solvers within an
3153: inexact Newton method.
3155: Not Collective
3157: Input Parameter:
3158: . snes - SNES context
3160: Output Parameter:
3161: . flag - PETSC_TRUE or PETSC_FALSE
3163: Notes:
3164: Currently, the default is to use a constant relative tolerance for
3165: the inner linear solvers. Alternatively, one can use the
3166: Eisenstat-Walker method, where the relative convergence tolerance
3167: is reset at each Newton iteration according progress of the nonlinear
3168: solver.
3170: Level: advanced
3172: Reference:
3173: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
3174: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
3176: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
3178: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
3179: @*/
3180: PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag)
3181: {
3185: *flag = snes->ksp_ewconv;
3186: return(0);
3187: }
3191: /*@
3192: SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
3193: convergence criteria for the linear solvers within an inexact
3194: Newton method.
3196: Logically Collective on SNES
3197:
3198: Input Parameters:
3199: + snes - SNES context
3200: . version - version 1, 2 (default is 2) or 3
3201: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
3202: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
3203: . gamma - multiplicative factor for version 2 rtol computation
3204: (0 <= gamma2 <= 1)
3205: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
3206: . alpha2 - power for safeguard
3207: - threshold - threshold for imposing safeguard (0 < threshold < 1)
3209: Note:
3210: Version 3 was contributed by Luis Chacon, June 2006.
3212: Use PETSC_DEFAULT to retain the default for any of the parameters.
3214: Level: advanced
3216: Reference:
3217: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
3218: inexact Newton method", Utah State University Math. Stat. Dept. Res.
3219: Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
3221: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
3223: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
3224: @*/
3225: PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
3226: PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
3227: {
3228: SNESKSPEW *kctx;
3231: kctx = (SNESKSPEW*)snes->kspconvctx;
3232: if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3241: if (version != PETSC_DEFAULT) kctx->version = version;
3242: if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
3243: if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max;
3244: if (gamma != PETSC_DEFAULT) kctx->gamma = gamma;
3245: if (alpha != PETSC_DEFAULT) kctx->alpha = alpha;
3246: if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2;
3247: if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
3248:
3249: if (kctx->version < 1 || kctx->version > 3) {
3250: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
3251: }
3252: if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
3253: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
3254: }
3255: if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
3256: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
3257: }
3258: if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
3259: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
3260: }
3261: if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
3262: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
3263: }
3264: if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
3265: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
3266: }
3267: return(0);
3268: }
3272: /*@
3273: SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
3274: convergence criteria for the linear solvers within an inexact
3275: Newton method.
3277: Not Collective
3278:
3279: Input Parameters:
3280: snes - SNES context
3282: Output Parameters:
3283: + version - version 1, 2 (default is 2) or 3
3284: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
3285: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
3286: . gamma - multiplicative factor for version 2 rtol computation
3287: (0 <= gamma2 <= 1)
3288: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
3289: . alpha2 - power for safeguard
3290: - threshold - threshold for imposing safeguard (0 < threshold < 1)
3292: Level: advanced
3294: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
3296: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
3297: @*/
3298: PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
3299: PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
3300: {
3301: SNESKSPEW *kctx;
3304: kctx = (SNESKSPEW*)snes->kspconvctx;
3305: if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
3306: if(version) *version = kctx->version;
3307: if(rtol_0) *rtol_0 = kctx->rtol_0;
3308: if(rtol_max) *rtol_max = kctx->rtol_max;
3309: if(gamma) *gamma = kctx->gamma;
3310: if(alpha) *alpha = kctx->alpha;
3311: if(alpha2) *alpha2 = kctx->alpha2;
3312: if(threshold) *threshold = kctx->threshold;
3313: return(0);
3314: }
3318: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
3319: {
3321: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
3322: PetscReal rtol=PETSC_DEFAULT,stol;
3325: if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
3326: if (!snes->iter) { /* first time in, so use the original user rtol */
3327: rtol = kctx->rtol_0;
3328: } else {
3329: if (kctx->version == 1) {
3330: rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
3331: if (rtol < 0.0) rtol = -rtol;
3332: stol = pow(kctx->rtol_last,kctx->alpha2);
3333: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
3334: } else if (kctx->version == 2) {
3335: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
3336: stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
3337: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
3338: } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
3339: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
3340: /* safeguard: avoid sharp decrease of rtol */
3341: stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
3342: stol = PetscMax(rtol,stol);
3343: rtol = PetscMin(kctx->rtol_0,stol);
3344: /* safeguard: avoid oversolving */
3345: stol = kctx->gamma*(snes->ttol)/snes->norm;
3346: stol = PetscMax(rtol,stol);
3347: rtol = PetscMin(kctx->rtol_0,stol);
3348: } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
3349: }
3350: /* safeguard: avoid rtol greater than one */
3351: rtol = PetscMin(rtol,kctx->rtol_max);
3352: KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
3353: PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
3354: return(0);
3355: }
3359: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
3360: {
3362: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
3363: PCSide pcside;
3364: Vec lres;
3367: if (!kctx) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
3368: KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
3369: SNESGetFunctionNorm(snes,&kctx->norm_last);
3370: if (kctx->version == 1) {
3371: KSPGetPCSide(ksp,&pcside);
3372: if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
3373: /* KSP residual is true linear residual */
3374: KSPGetResidualNorm(ksp,&kctx->lresid_last);
3375: } else {
3376: /* KSP residual is preconditioned residual */
3377: /* compute true linear residual norm */
3378: VecDuplicate(b,&lres);
3379: MatMult(snes->jacobian,x,lres);
3380: VecAYPX(lres,-1.0,b);
3381: VecNorm(lres,NORM_2,&kctx->lresid_last);
3382: VecDestroy(&lres);
3383: }
3384: }
3385: return(0);
3386: }
3390: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
3391: {
3395: if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x); }
3396: KSPSolve(ksp,b,x);
3397: if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
3398: return(0);
3399: }
3403: /*@
3404: SNESSetDM - Sets the DM that may be used by some preconditioners
3406: Logically Collective on SNES
3408: Input Parameters:
3409: + snes - the preconditioner context
3410: - dm - the dm
3412: Level: intermediate
3415: .seealso: SNESGetDM(), KSPSetDM(), KSPGetDM()
3416: @*/
3417: PetscErrorCode SNESSetDM(SNES snes,DM dm)
3418: {
3420: KSP ksp;
3424: if (dm) {PetscObjectReference((PetscObject)dm);}
3425: DMDestroy(&snes->dm);
3426: snes->dm = dm;
3427: SNESGetKSP(snes,&ksp);
3428: KSPSetDM(ksp,dm);
3429: KSPSetDMActive(ksp,PETSC_FALSE);
3430: return(0);
3431: }
3435: /*@
3436: SNESGetDM - Gets the DM that may be used by some preconditioners
3438: Not Collective but DM obtained is parallel on SNES
3440: Input Parameter:
3441: . snes - the preconditioner context
3443: Output Parameter:
3444: . dm - the dm
3446: Level: intermediate
3449: .seealso: SNESSetDM(), KSPSetDM(), KSPGetDM()
3450: @*/
3451: PetscErrorCode SNESGetDM(SNES snes,DM *dm)
3452: {
3455: *dm = snes->dm;
3456: return(0);
3457: }
3461: /*@
3462: SNESSetPC - Sets the nonlinear preconditioner to be used.
3464: Collective on SNES
3466: Input Parameters:
3467: + snes - iterative context obtained from SNESCreate()
3468: - pc - the preconditioner object
3470: Notes:
3471: Use SNESGetPC() to retrieve the preconditioner context (for example,
3472: to configure it using the API).
3474: Level: developer
3476: .keywords: SNES, set, precondition
3477: .seealso: SNESGetPC()
3478: @*/
3479: PetscErrorCode SNESSetPC(SNES snes, SNES pc)
3480: {
3487: PetscObjectReference((PetscObject) pc);
3488: SNESDestroy(&snes->pc);
3489: snes->pc = pc;
3490: PetscLogObjectParent(snes, snes->pc);
3491: return(0);
3492: }
3496: /*@
3497: SNESGetPC - Returns a pointer to the nonlinear preconditioning context set with SNESSetPC().
3499: Not Collective
3501: Input Parameter:
3502: . snes - iterative context obtained from SNESCreate()
3504: Output Parameter:
3505: . pc - preconditioner context
3507: Level: developer
3509: .keywords: SNES, get, preconditioner
3510: .seealso: SNESSetPC()
3511: @*/
3512: PetscErrorCode SNESGetPC(SNES snes, SNES *pc)
3513: {
3519: if (!snes->pc) {
3520: SNESCreate(((PetscObject) snes)->comm, &snes->pc);
3521: PetscObjectIncrementTabLevel((PetscObject) snes->pc, (PetscObject) snes, 1);
3522: PetscLogObjectParent(snes, snes->pc);
3523: }
3524: *pc = snes->pc;
3525: return(0);
3526: }
3528: #if defined(PETSC_HAVE_MATLAB_ENGINE)
3529: #include <mex.h>
3531: typedef struct {char *funcname; mxArray *ctx;} SNESMatlabContext;
3535: /*
3536: SNESComputeFunction_Matlab - Calls the function that has been set with
3537: SNESSetFunctionMatlab().
3539: Collective on SNES
3541: Input Parameters:
3542: + snes - the SNES context
3543: - x - input vector
3545: Output Parameter:
3546: . y - function vector, as set by SNESSetFunction()
3548: Notes:
3549: SNESComputeFunction() is typically used within nonlinear solvers
3550: implementations, so most users would not generally call this routine
3551: themselves.
3553: Level: developer
3555: .keywords: SNES, nonlinear, compute, function
3557: .seealso: SNESSetFunction(), SNESGetFunction()
3558: */
3559: PetscErrorCode SNESComputeFunction_Matlab(SNES snes,Vec x,Vec y, void *ctx)
3560: {
3561: PetscErrorCode ierr;
3562: SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3563: int nlhs = 1,nrhs = 5;
3564: mxArray *plhs[1],*prhs[5];
3565: long long int lx = 0,ly = 0,ls = 0;
3566:
3574: /* call Matlab function in ctx with arguments x and y */
3576: PetscMemcpy(&ls,&snes,sizeof(snes));
3577: PetscMemcpy(&lx,&x,sizeof(x));
3578: PetscMemcpy(&ly,&y,sizeof(x));
3579: prhs[0] = mxCreateDoubleScalar((double)ls);
3580: prhs[1] = mxCreateDoubleScalar((double)lx);
3581: prhs[2] = mxCreateDoubleScalar((double)ly);
3582: prhs[3] = mxCreateString(sctx->funcname);
3583: prhs[4] = sctx->ctx;
3584: mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeFunctionInternal");
3585: mxGetScalar(plhs[0]);
3586: mxDestroyArray(prhs[0]);
3587: mxDestroyArray(prhs[1]);
3588: mxDestroyArray(prhs[2]);
3589: mxDestroyArray(prhs[3]);
3590: mxDestroyArray(plhs[0]);
3591: return(0);
3592: }
3597: /*
3598: SNESSetFunctionMatlab - Sets the function evaluation routine and function
3599: vector for use by the SNES routines in solving systems of nonlinear
3600: equations from MATLAB. Here the function is a string containing the name of a MATLAB function
3602: Logically Collective on SNES
3604: Input Parameters:
3605: + snes - the SNES context
3606: . r - vector to store function value
3607: - func - function evaluation routine
3609: Calling sequence of func:
3610: $ func (SNES snes,Vec x,Vec f,void *ctx);
3613: Notes:
3614: The Newton-like methods typically solve linear systems of the form
3615: $ f'(x) x = -f(x),
3616: where f'(x) denotes the Jacobian matrix and f(x) is the function.
3618: Level: beginner
3620: .keywords: SNES, nonlinear, set, function
3622: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3623: */
3624: PetscErrorCode SNESSetFunctionMatlab(SNES snes,Vec r,const char *func,mxArray *ctx)
3625: {
3626: PetscErrorCode ierr;
3627: SNESMatlabContext *sctx;
3630: /* currently sctx is memory bleed */
3631: PetscMalloc(sizeof(SNESMatlabContext),&sctx);
3632: PetscStrallocpy(func,&sctx->funcname);
3633: /*
3634: This should work, but it doesn't
3635: sctx->ctx = ctx;
3636: mexMakeArrayPersistent(sctx->ctx);
3637: */
3638: sctx->ctx = mxDuplicateArray(ctx);
3639: SNESSetFunction(snes,r,SNESComputeFunction_Matlab,sctx);
3640: return(0);
3641: }
3645: /*
3646: SNESComputeJacobian_Matlab - Calls the function that has been set with
3647: SNESSetJacobianMatlab().
3649: Collective on SNES
3651: Input Parameters:
3652: + snes - the SNES context
3653: . x - input vector
3654: . A, B - the matrices
3655: - ctx - user context
3657: Output Parameter:
3658: . flag - structure of the matrix
3660: Level: developer
3662: .keywords: SNES, nonlinear, compute, function
3664: .seealso: SNESSetFunction(), SNESGetFunction()
3665: @*/
3666: PetscErrorCode SNESComputeJacobian_Matlab(SNES snes,Vec x,Mat *A,Mat *B,MatStructure *flag, void *ctx)
3667: {
3668: PetscErrorCode ierr;
3669: SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3670: int nlhs = 2,nrhs = 6;
3671: mxArray *plhs[2],*prhs[6];
3672: long long int lx = 0,lA = 0,ls = 0, lB = 0;
3673:
3678: /* call Matlab function in ctx with arguments x and y */
3680: PetscMemcpy(&ls,&snes,sizeof(snes));
3681: PetscMemcpy(&lx,&x,sizeof(x));
3682: PetscMemcpy(&lA,A,sizeof(x));
3683: PetscMemcpy(&lB,B,sizeof(x));
3684: prhs[0] = mxCreateDoubleScalar((double)ls);
3685: prhs[1] = mxCreateDoubleScalar((double)lx);
3686: prhs[2] = mxCreateDoubleScalar((double)lA);
3687: prhs[3] = mxCreateDoubleScalar((double)lB);
3688: prhs[4] = mxCreateString(sctx->funcname);
3689: prhs[5] = sctx->ctx;
3690: mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESComputeJacobianInternal");
3691: mxGetScalar(plhs[0]);
3692: *flag = (MatStructure) mxGetScalar(plhs[1]);
3693: mxDestroyArray(prhs[0]);
3694: mxDestroyArray(prhs[1]);
3695: mxDestroyArray(prhs[2]);
3696: mxDestroyArray(prhs[3]);
3697: mxDestroyArray(prhs[4]);
3698: mxDestroyArray(plhs[0]);
3699: mxDestroyArray(plhs[1]);
3700: return(0);
3701: }
3706: /*
3707: SNESSetJacobianMatlab - Sets the Jacobian function evaluation routine and two empty Jacobian matrices
3708: vector for use by the SNES routines in solving systems of nonlinear
3709: equations from MATLAB. Here the function is a string containing the name of a MATLAB function
3711: Logically Collective on SNES
3713: Input Parameters:
3714: + snes - the SNES context
3715: . A,B - Jacobian matrices
3716: . func - function evaluation routine
3717: - ctx - user context
3719: Calling sequence of func:
3720: $ flag = func (SNES snes,Vec x,Mat A,Mat B,void *ctx);
3723: Level: developer
3725: .keywords: SNES, nonlinear, set, function
3727: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3728: */
3729: PetscErrorCode SNESSetJacobianMatlab(SNES snes,Mat A,Mat B,const char *func,mxArray *ctx)
3730: {
3731: PetscErrorCode ierr;
3732: SNESMatlabContext *sctx;
3735: /* currently sctx is memory bleed */
3736: PetscMalloc(sizeof(SNESMatlabContext),&sctx);
3737: PetscStrallocpy(func,&sctx->funcname);
3738: /*
3739: This should work, but it doesn't
3740: sctx->ctx = ctx;
3741: mexMakeArrayPersistent(sctx->ctx);
3742: */
3743: sctx->ctx = mxDuplicateArray(ctx);
3744: SNESSetJacobian(snes,A,B,SNESComputeJacobian_Matlab,sctx);
3745: return(0);
3746: }
3750: /*
3751: SNESMonitor_Matlab - Calls the function that has been set with SNESMonitorSetMatlab().
3753: Collective on SNES
3755: .seealso: SNESSetFunction(), SNESGetFunction()
3756: @*/
3757: PetscErrorCode SNESMonitor_Matlab(SNES snes,PetscInt it, PetscReal fnorm, void *ctx)
3758: {
3759: PetscErrorCode ierr;
3760: SNESMatlabContext *sctx = (SNESMatlabContext *)ctx;
3761: int nlhs = 1,nrhs = 6;
3762: mxArray *plhs[1],*prhs[6];
3763: long long int lx = 0,ls = 0;
3764: Vec x=snes->vec_sol;
3765:
3769: PetscMemcpy(&ls,&snes,sizeof(snes));
3770: PetscMemcpy(&lx,&x,sizeof(x));
3771: prhs[0] = mxCreateDoubleScalar((double)ls);
3772: prhs[1] = mxCreateDoubleScalar((double)it);
3773: prhs[2] = mxCreateDoubleScalar((double)fnorm);
3774: prhs[3] = mxCreateDoubleScalar((double)lx);
3775: prhs[4] = mxCreateString(sctx->funcname);
3776: prhs[5] = sctx->ctx;
3777: mexCallMATLAB(nlhs,plhs,nrhs,prhs,"PetscSNESMonitorInternal");
3778: mxGetScalar(plhs[0]);
3779: mxDestroyArray(prhs[0]);
3780: mxDestroyArray(prhs[1]);
3781: mxDestroyArray(prhs[2]);
3782: mxDestroyArray(prhs[3]);
3783: mxDestroyArray(prhs[4]);
3784: mxDestroyArray(plhs[0]);
3785: return(0);
3786: }
3791: /*
3792: SNESMonitorSetMatlab - Sets the monitor function from MATLAB
3794: Level: developer
3796: .keywords: SNES, nonlinear, set, function
3798: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
3799: */
3800: PetscErrorCode SNESMonitorSetMatlab(SNES snes,const char *func,mxArray *ctx)
3801: {
3802: PetscErrorCode ierr;
3803: SNESMatlabContext *sctx;
3806: /* currently sctx is memory bleed */
3807: PetscMalloc(sizeof(SNESMatlabContext),&sctx);
3808: PetscStrallocpy(func,&sctx->funcname);
3809: /*
3810: This should work, but it doesn't
3811: sctx->ctx = ctx;
3812: mexMakeArrayPersistent(sctx->ctx);
3813: */
3814: sctx->ctx = mxDuplicateArray(ctx);
3815: SNESMonitorSet(snes,SNESMonitor_Matlab,sctx,PETSC_NULL);
3816: return(0);
3817: }
3819: #endif