Actual source code: snes.c
1: #define PETSCSNES_DLL
3: #include private/snesimpl.h
5: PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
6: PetscFList SNESList = PETSC_NULL;
8: /* Logging support */
9: PetscCookie SNES_COOKIE;
10: PetscLogEvent SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
14: /*@
15: SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
16: in the functions domain. For example, negative pressure.
18: Collective on SNES
20: Input Parameters:
21: . SNES - the SNES context
23: Level: advanced
25: .keywords: SNES, view
27: .seealso: SNESCreate(), SNESSetFunction()
28: @*/
29: PetscErrorCode SNESSetFunctionDomainError(SNES snes)
30: {
33: snes->domainerror = PETSC_TRUE;
34: return(0);
35: }
39: /*@C
40: SNESView - Prints the SNES data structure.
42: Collective on SNES
44: Input Parameters:
45: + SNES - the SNES context
46: - viewer - visualization context
48: Options Database Key:
49: . -snes_view - Calls SNESView() at end of SNESSolve()
51: Notes:
52: The available visualization contexts include
53: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
54: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
55: output where only the first processor opens
56: the file. All other processors send their
57: data to the first processor to print.
59: The user can open an alternative visualization context with
60: PetscViewerASCIIOpen() - output to a specified file.
62: Level: beginner
64: .keywords: SNES, view
66: .seealso: PetscViewerASCIIOpen()
67: @*/
68: PetscErrorCode SNESView(SNES snes,PetscViewer viewer)
69: {
70: SNESKSPEW *kctx;
71: PetscErrorCode ierr;
72: KSP ksp;
73: const SNESType type;
74: PetscTruth iascii,isstring;
78: if (!viewer) {
79: PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);
80: }
84: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
85: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
86: if (iascii) {
87: if (((PetscObject)snes)->prefix) {
88: PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",((PetscObject)snes)->prefix);
89: } else {
90: PetscViewerASCIIPrintf(viewer,"SNES Object:\n");
91: }
92: SNESGetType(snes,&type);
93: if (type) {
94: PetscViewerASCIIPrintf(viewer," type: %s\n",type);
95: } else {
96: PetscViewerASCIIPrintf(viewer," type: not set yet\n");
97: }
98: if (snes->ops->view) {
99: PetscViewerASCIIPushTab(viewer);
100: (*snes->ops->view)(snes,viewer);
101: PetscViewerASCIIPopTab(viewer);
102: }
103: PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
104: PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n",
105: snes->rtol,snes->abstol,snes->xtol);
106: PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);
107: PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);
108: if (snes->ksp_ewconv) {
109: kctx = (SNESKSPEW *)snes->kspconvctx;
110: if (kctx) {
111: PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
112: PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
113: PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
114: }
115: }
116: } else if (isstring) {
117: SNESGetType(snes,&type);
118: PetscViewerStringSPrintf(viewer," %-3.3s",type);
119: }
120: SNESGetKSP(snes,&ksp);
121: PetscViewerASCIIPushTab(viewer);
122: KSPView(ksp,viewer);
123: PetscViewerASCIIPopTab(viewer);
124: return(0);
125: }
127: /*
128: We retain a list of functions that also take SNES command
129: line options. These are called at the end SNESSetFromOptions()
130: */
131: #define MAXSETFROMOPTIONS 5
132: static PetscInt numberofsetfromoptions;
133: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
137: /*@C
138: SNESAddOptionsChecker - Adds an additional function to check for SNES options.
140: Not Collective
142: Input Parameter:
143: . snescheck - function that checks for options
145: Level: developer
147: .seealso: SNESSetFromOptions()
148: @*/
149: PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
150: {
152: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
153: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
154: }
155: othersetfromoptions[numberofsetfromoptions++] = snescheck;
156: return(0);
157: }
161: /*@
162: SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
164: Collective on SNES
166: Input Parameter:
167: . snes - the SNES context
169: Options Database Keys:
170: + -snes_type <type> - ls, tr, umls, umtr, test
171: . -snes_stol - convergence tolerance in terms of the norm
172: of the change in the solution between steps
173: . -snes_atol <abstol> - absolute tolerance of residual norm
174: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
175: . -snes_max_it <max_it> - maximum number of iterations
176: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
177: . -snes_max_fail <max_fail> - maximum number of failures
178: . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops
179: . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild)
180: . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild)
181: . -snes_trtol <trtol> - trust region tolerance
182: . -snes_no_convergence_test - skip convergence test in nonlinear
183: solver; hence iterations will continue until max_it
184: or some other criterion is reached. Saves expense
185: of convergence test
186: . -snes_monitor <optional filename> - prints residual norm at each iteration. if no
187: filename given prints to stdout
188: . -snes_monitor_solution - plots solution at each iteration
189: . -snes_monitor_residual - plots residual (not its norm) at each iteration
190: . -snes_monitor_solution_update - plots update to solution at each iteration
191: . -snes_monitor_draw - plots residual norm at each iteration
192: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
193: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
194: - -snes_converged_reason - print the reason for convergence/divergence after each solve
196: Options Database for Eisenstat-Walker method:
197: + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
198: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
199: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
200: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
201: . -snes_ksp_ew_gamma <gamma> - Sets gamma
202: . -snes_ksp_ew_alpha <alpha> - Sets alpha
203: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
204: - -snes_ksp_ew_threshold <threshold> - Sets threshold
206: Notes:
207: To see all options, run your program with the -help option or consult
208: the users manual.
210: Level: beginner
212: .keywords: SNES, nonlinear, set, options, database
214: .seealso: SNESSetOptionsPrefix()
215: @*/
216: PetscErrorCode SNESSetFromOptions(SNES snes)
217: {
218: PetscTruth flg;
219: PetscInt i,indx,lag;
220: const char *deft = SNESLS;
221: const char *convtests[] = {"default","skip"};
222: SNESKSPEW *kctx = NULL;
223: char type[256], monfilename[PETSC_MAX_PATH_LEN];
224: PetscViewerASCIIMonitor monviewer;
225: PetscErrorCode ierr;
230: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
231: PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");
232: if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
233: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
234: if (flg) {
235: SNESSetType(snes,type);
236: } else if (!((PetscObject)snes)->type_name) {
237: SNESSetType(snes,deft);
238: }
239: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
241: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
242: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);
244: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
245: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
246: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
247: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
248: PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,PETSC_NULL);
250: PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg);
251: if (flg) {
252: SNESSetLagPreconditioner(snes,lag);
253: }
254: PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg);
255: if (flg) {
256: SNESSetLagJacobian(snes,lag);
257: }
259: PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
260: if (flg) {
261: switch (indx) {
262: case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL,PETSC_NULL); break;
263: case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL,PETSC_NULL); break;
264: }
265: }
267: PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
268: if (flg) {
269: snes->printreason = PETSC_TRUE;
270: }
272: kctx = (SNESKSPEW *)snes->kspconvctx;
274: PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
276: PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
277: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
278: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
279: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
280: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
281: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
282: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);
284: PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);
285: if (flg) {SNESMonitorCancel(snes);}
287: PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
288: if (flg) {
289: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
290: SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
291: }
293: PetscOptionsString("-snes_monitor_range","Monitor range of elements of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
294: if (flg) {
295: SNESMonitorSet(snes,SNESMonitorRange,0,0);
296: }
298: PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
299: if (flg) {
300: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
301: SNESMonitorSetRatio(snes,monviewer);
302: }
304: PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
305: if (flg) {
306: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,((PetscObject)snes)->tablevel,&monviewer);
307: SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
308: }
310: PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);
311: if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
312: PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);
313: if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
314: PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);
315: if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
316: PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);
317: if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
318: PetscOptionsName("-snes_monitor_range_draw","Plot function range at each iteration","SNESMonitorLG",&flg);
319: if (flg) {SNESMonitorSet(snes,SNESMonitorLGRange,PETSC_NULL,PETSC_NULL);}
321: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
322: if (flg) {
323: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
324: PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
325: }
327: for(i = 0; i < numberofsetfromoptions; i++) {
328: (*othersetfromoptions[i])(snes);
329: }
331: if (snes->ops->setfromoptions) {
332: (*snes->ops->setfromoptions)(snes);
333: }
334: PetscOptionsEnd();
336:
337: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
338: KSPSetFromOptions(snes->ksp);
340: return(0);
341: }
346: /*@
347: SNESSetApplicationContext - Sets the optional user-defined context for
348: the nonlinear solvers.
350: Collective on SNES
352: Input Parameters:
353: + snes - the SNES context
354: - usrP - optional user context
356: Level: intermediate
358: .keywords: SNES, nonlinear, set, application, context
360: .seealso: SNESGetApplicationContext()
361: @*/
362: PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP)
363: {
366: snes->user = usrP;
367: return(0);
368: }
372: /*@C
373: SNESGetApplicationContext - Gets the user-defined context for the
374: nonlinear solvers.
376: Not Collective
378: Input Parameter:
379: . snes - SNES context
381: Output Parameter:
382: . usrP - user context
384: Level: intermediate
386: .keywords: SNES, nonlinear, get, application, context
388: .seealso: SNESSetApplicationContext()
389: @*/
390: PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP)
391: {
394: *usrP = snes->user;
395: return(0);
396: }
400: /*@
401: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
402: at this time.
404: Not Collective
406: Input Parameter:
407: . snes - SNES context
409: Output Parameter:
410: . iter - iteration number
412: Notes:
413: For example, during the computation of iteration 2 this would return 1.
415: This is useful for using lagged Jacobians (where one does not recompute the
416: Jacobian at each SNES iteration). For example, the code
417: .vb
418: SNESGetIterationNumber(snes,&it);
419: if (!(it % 2)) {
420: [compute Jacobian here]
421: }
422: .ve
423: can be used in your ComputeJacobian() function to cause the Jacobian to be
424: recomputed every second SNES iteration.
426: Level: intermediate
428: .keywords: SNES, nonlinear, get, iteration, number,
430: .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
431: @*/
432: PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter)
433: {
437: *iter = snes->iter;
438: return(0);
439: }
443: /*@
444: SNESGetFunctionNorm - Gets the norm of the current function that was set
445: with SNESSSetFunction().
447: Collective on SNES
449: Input Parameter:
450: . snes - SNES context
452: Output Parameter:
453: . fnorm - 2-norm of function
455: Level: intermediate
457: .keywords: SNES, nonlinear, get, function, norm
459: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
460: @*/
461: PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
462: {
466: *fnorm = snes->norm;
467: return(0);
468: }
472: /*@
473: SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
474: attempted by the nonlinear solver.
476: Not Collective
478: Input Parameter:
479: . snes - SNES context
481: Output Parameter:
482: . nfails - number of unsuccessful steps attempted
484: Notes:
485: This counter is reset to zero for each successive call to SNESSolve().
487: Level: intermediate
489: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
491: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
492: SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
493: @*/
494: PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
495: {
499: *nfails = snes->numFailures;
500: return(0);
501: }
505: /*@
506: SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
507: attempted by the nonlinear solver before it gives up.
509: Not Collective
511: Input Parameters:
512: + snes - SNES context
513: - maxFails - maximum of unsuccessful steps
515: Level: intermediate
517: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
519: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
520: SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
521: @*/
522: PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
523: {
526: snes->maxFailures = maxFails;
527: return(0);
528: }
532: /*@
533: SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
534: attempted by the nonlinear solver before it gives up.
536: Not Collective
538: Input Parameter:
539: . snes - SNES context
541: Output Parameter:
542: . maxFails - maximum of unsuccessful steps
544: Level: intermediate
546: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
548: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
549: SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
550:
551: @*/
552: PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
553: {
557: *maxFails = snes->maxFailures;
558: return(0);
559: }
563: /*@
564: SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
565: done by SNES.
567: Not Collective
569: Input Parameter:
570: . snes - SNES context
572: Output Parameter:
573: . nfuncs - number of evaluations
575: Level: intermediate
577: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
579: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
580: @*/
581: PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
582: {
586: *nfuncs = snes->nfuncs;
587: return(0);
588: }
592: /*@
593: SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
594: linear solvers.
596: Not Collective
598: Input Parameter:
599: . snes - SNES context
601: Output Parameter:
602: . nfails - number of failed solves
604: Notes:
605: This counter is reset to zero for each successive call to SNESSolve().
607: Level: intermediate
609: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
611: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures()
612: @*/
613: PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
614: {
618: *nfails = snes->numLinearSolveFailures;
619: return(0);
620: }
624: /*@
625: SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
626: allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
628: Collective on SNES
630: Input Parameters:
631: + snes - SNES context
632: - maxFails - maximum allowed linear solve failures
634: Level: intermediate
636: Notes: By default this is 0; that is SNES returns on the first failed linear solve
638: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
640: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
641: @*/
642: PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
643: {
646: snes->maxLinearSolveFailures = maxFails;
647: return(0);
648: }
652: /*@
653: SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
654: are allowed before SNES terminates
656: Not Collective
658: Input Parameter:
659: . snes - SNES context
661: Output Parameter:
662: . maxFails - maximum of unsuccessful solves allowed
664: Level: intermediate
666: Notes: By default this is 1; that is SNES returns on the first failed linear solve
668: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
670: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolveIterations(), SNESSetMaxLinearSolveFailures(),
671: @*/
672: PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
673: {
677: *maxFails = snes->maxLinearSolveFailures;
678: return(0);
679: }
683: /*@
684: SNESGetLinearSolveIterations - Gets the total number of linear iterations
685: used by the nonlinear solver.
687: Not Collective
689: Input Parameter:
690: . snes - SNES context
692: Output Parameter:
693: . lits - number of linear iterations
695: Notes:
696: This counter is reset to zero for each successive call to SNESSolve().
698: Level: intermediate
700: .keywords: SNES, nonlinear, get, number, linear, iterations
702: .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm()S, NESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
703: @*/
704: PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
705: {
709: *lits = snes->linear_its;
710: return(0);
711: }
715: /*@
716: SNESGetKSP - Returns the KSP context for a SNES solver.
718: Not Collective, but if SNES object is parallel, then KSP object is parallel
720: Input Parameter:
721: . snes - the SNES context
723: Output Parameter:
724: . ksp - the KSP context
726: Notes:
727: The user can then directly manipulate the KSP context to set various
728: options, etc. Likewise, the user can then extract and manipulate the
729: PC contexts as well.
731: Level: beginner
733: .keywords: SNES, nonlinear, get, KSP, context
735: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
736: @*/
737: PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp)
738: {
745: if (!snes->ksp) {
746: KSPCreate(((PetscObject)snes)->comm,&snes->ksp);
747: PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1);
748: PetscLogObjectParent(snes,snes->ksp);
749: }
750: *ksp = snes->ksp;
751: return(0);
752: }
756: /*@
757: SNESSetKSP - Sets a KSP context for the SNES object to use
759: Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
761: Input Parameters:
762: + snes - the SNES context
763: - ksp - the KSP context
765: Notes:
766: The SNES object already has its KSP object, you can obtain with SNESGetKSP()
767: so this routine is rarely needed.
769: The KSP object that is already in the SNES object has its reference count
770: decreased by one.
772: Level: developer
774: .keywords: SNES, nonlinear, get, KSP, context
776: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
777: @*/
778: PetscErrorCode SNESSetKSP(SNES snes,KSP ksp)
779: {
786: PetscObjectReference((PetscObject)ksp);
787: if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
788: snes->ksp = ksp;
789: return(0);
790: }
792: #if 0
795: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
796: {
798: return(0);
799: }
800: #endif
802: /* -----------------------------------------------------------*/
805: /*@
806: SNESCreate - Creates a nonlinear solver context.
808: Collective on MPI_Comm
810: Input Parameters:
811: . comm - MPI communicator
813: Output Parameter:
814: . outsnes - the new SNES context
816: Options Database Keys:
817: + -snes_mf - Activates default matrix-free Jacobian-vector products,
818: and no preconditioning matrix
819: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
820: products, and a user-provided preconditioning matrix
821: as set by SNESSetJacobian()
822: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
824: Level: beginner
826: .keywords: SNES, nonlinear, create, context
828: .seealso: SNESSolve(), SNESDestroy(), SNES, SNESSetLagPreconditioner()
830: @*/
831: PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes)
832: {
833: PetscErrorCode ierr;
834: SNES snes;
835: SNESKSPEW *kctx;
839: *outsnes = PETSC_NULL;
840: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
841: SNESInitializePackage(PETSC_NULL);
842: #endif
844: PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
846: snes->ops->converged = SNESDefaultConverged;
847: snes->max_its = 50;
848: snes->max_funcs = 10000;
849: snes->norm = 0.0;
850: snes->rtol = 1.e-8;
851: snes->ttol = 0.0;
852: snes->abstol = 1.e-50;
853: snes->xtol = 1.e-8;
854: snes->deltatol = 1.e-12;
855: snes->nfuncs = 0;
856: snes->numFailures = 0;
857: snes->maxFailures = 1;
858: snes->linear_its = 0;
859: snes->lagjacobian = 1;
860: snes->lagpreconditioner = 1;
861: snes->numbermonitors = 0;
862: snes->data = 0;
863: snes->setupcalled = PETSC_FALSE;
864: snes->ksp_ewconv = PETSC_FALSE;
865: snes->vwork = 0;
866: snes->nwork = 0;
867: snes->conv_hist_len = 0;
868: snes->conv_hist_max = 0;
869: snes->conv_hist = PETSC_NULL;
870: snes->conv_hist_its = PETSC_NULL;
871: snes->conv_hist_reset = PETSC_TRUE;
872: snes->reason = SNES_CONVERGED_ITERATING;
874: snes->numLinearSolveFailures = 0;
875: snes->maxLinearSolveFailures = 1;
877: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
878: PetscNewLog(snes,SNESKSPEW,&kctx);
879: snes->kspconvctx = (void*)kctx;
880: kctx->version = 2;
881: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
882: this was too large for some test cases */
883: kctx->rtol_last = 0;
884: kctx->rtol_max = .9;
885: kctx->gamma = 1.0;
886: kctx->alpha = .5*(1.0 + sqrt(5.0));
887: kctx->alpha2 = kctx->alpha;
888: kctx->threshold = .1;
889: kctx->lresid_last = 0;
890: kctx->norm_last = 0;
892: *outsnes = snes;
893: PetscPublishAll(snes);
894: return(0);
895: }
899: /*@C
900: SNESSetFunction - Sets the function evaluation routine and function
901: vector for use by the SNES routines in solving systems of nonlinear
902: equations.
904: Collective on SNES
906: Input Parameters:
907: + snes - the SNES context
908: . r - vector to store function value
909: . func - function evaluation routine
910: - ctx - [optional] user-defined context for private data for the
911: function evaluation routine (may be PETSC_NULL)
913: Calling sequence of func:
914: $ func (SNES snes,Vec x,Vec f,void *ctx);
916: . f - function vector
917: - ctx - optional user-defined function context
919: Notes:
920: The Newton-like methods typically solve linear systems of the form
921: $ f'(x) x = -f(x),
922: where f'(x) denotes the Jacobian matrix and f(x) is the function.
924: Level: beginner
926: .keywords: SNES, nonlinear, set, function
928: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
929: @*/
930: PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
931: {
937: PetscObjectReference((PetscObject)r);
938: if (snes->vec_func) { VecDestroy(snes->vec_func); }
939: snes->ops->computefunction = func;
940: snes->vec_func = r;
941: snes->funP = ctx;
942: return(0);
943: }
945: /* --------------------------------------------------------------- */
948: /*@C
949: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
950: it assumes a zero right hand side.
952: Collective on SNES
954: Input Parameter:
955: . snes - the SNES context
957: Output Parameter:
958: . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
960: Level: intermediate
962: .keywords: SNES, nonlinear, get, function, right hand side
964: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
965: @*/
966: PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs)
967: {
971: *rhs = snes->vec_rhs;
972: return(0);
973: }
977: /*@
978: SNESComputeFunction - Calls the function that has been set with
979: SNESSetFunction().
981: Collective on SNES
983: Input Parameters:
984: + snes - the SNES context
985: - x - input vector
987: Output Parameter:
988: . y - function vector, as set by SNESSetFunction()
990: Notes:
991: SNESComputeFunction() is typically used within nonlinear solvers
992: implementations, so most users would not generally call this routine
993: themselves.
995: Level: developer
997: .keywords: SNES, nonlinear, compute, function
999: .seealso: SNESSetFunction(), SNESGetFunction()
1000: @*/
1001: PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y)
1002: {
1012: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
1013: if (snes->ops->computefunction) {
1014: PetscStackPush("SNES user function");
1015: CHKMEMQ;
1016: (*snes->ops->computefunction)(snes,x,y,snes->funP);
1017: CHKMEMQ;
1018: PetscStackPop;
1019: if (PetscExceptionValue(ierr)) {
1020: PetscErrorCode pPetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
1021: }
1022:
1023: } else if (snes->vec_rhs) {
1024: MatMult(snes->jacobian, x, y);
1025: } else {
1026: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
1027: }
1028: if (snes->vec_rhs) {
1029: VecAXPY(y,-1.0,snes->vec_rhs);
1030: }
1031: snes->nfuncs++;
1032: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
1033: return(0);
1034: }
1038: /*@
1039: SNESComputeJacobian - Computes the Jacobian matrix that has been
1040: set with SNESSetJacobian().
1042: Collective on SNES and Mat
1044: Input Parameters:
1045: + snes - the SNES context
1046: - x - input vector
1048: Output Parameters:
1049: + A - Jacobian matrix
1050: . B - optional preconditioning matrix
1051: - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1053: Options Database Keys:
1054: + -snes_lag_preconditioner <lag>
1055: - -snes_lag_jacobian <lag>
1057: Notes:
1058: Most users should not need to explicitly call this routine, as it
1059: is used internally within the nonlinear solvers.
1061: See KSPSetOperators() for important information about setting the
1062: flag parameter.
1064: Level: developer
1066: .keywords: SNES, compute, Jacobian, matrix
1068: .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure, SNESSetLagPreconditioner(), SNESSetLagJacobian()
1069: @*/
1070: PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1071: {
1073: PetscTruth flag;
1080: if (!snes->ops->computejacobian) return(0);
1082: /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */
1084: if (snes->lagjacobian == -2) {
1085: snes->lagjacobian = -1;
1086: PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n");
1087: } else if (snes->lagjacobian == -1) {
1088: *flg = SAME_PRECONDITIONER;
1089: PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n");
1090: PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1091: if (flag) {
1092: MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1093: MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1094: }
1095: return(0);
1096: } else if (snes->lagjacobian > 1 && snes->iter % snes->lagjacobian) {
1097: *flg = SAME_PRECONDITIONER;
1098: PetscInfo2(snes,"Reusing Jacobian/preconditioner because lag is %D and SNES iteration is %D\n",snes->lagjacobian,snes->iter);
1099: PetscTypeCompare((PetscObject)*A,MATMFFD,&flag);
1100: if (flag) {
1101: MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);
1102: MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);
1103: }
1104: return(0);
1105: }
1107: *flg = DIFFERENT_NONZERO_PATTERN;
1108: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
1109: PetscStackPush("SNES user Jacobian function");
1110: CHKMEMQ;
1111: (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1112: CHKMEMQ;
1113: PetscStackPop;
1114: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
1116: if (snes->lagpreconditioner == -2) {
1117: PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n");
1118: snes->lagpreconditioner = -1;
1119: } else if (snes->lagpreconditioner == -1) {
1120: *flg = SAME_PRECONDITIONER;
1121: PetscInfo(snes,"Reusing preconditioner because lag is -1\n");
1122: } else if (snes->lagpreconditioner > 1 && snes->iter % snes->lagpreconditioner) {
1123: *flg = SAME_PRECONDITIONER;
1124: PetscInfo2(snes,"Reusing preconditioner because lag is %D and SNES iteration is %D\n",snes->lagpreconditioner,snes->iter);
1125: }
1127: /* make sure user returned a correct Jacobian and preconditioner */
1130: return(0);
1131: }
1135: /*@C
1136: SNESSetJacobian - Sets the function to compute Jacobian as well as the
1137: location to store the matrix.
1139: Collective on SNES and Mat
1141: Input Parameters:
1142: + snes - the SNES context
1143: . A - Jacobian matrix
1144: . B - preconditioner matrix (usually same as the Jacobian)
1145: . func - Jacobian evaluation routine
1146: - ctx - [optional] user-defined context for private data for the
1147: Jacobian evaluation routine (may be PETSC_NULL)
1149: Calling sequence of func:
1150: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
1152: + x - input vector
1153: . A - Jacobian matrix
1154: . B - preconditioner matrix, usually the same as A
1155: . flag - flag indicating information about the preconditioner matrix
1156: structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1157: - ctx - [optional] user-defined Jacobian context
1159: Notes:
1160: See KSPSetOperators() for important information about setting the flag
1161: output parameter in the routine func(). Be sure to read this information!
1163: The routine func() takes Mat * as the matrix arguments rather than Mat.
1164: This allows the Jacobian evaluation routine to replace A and/or B with a
1165: completely new new matrix structure (not just different matrix elements)
1166: when appropriate, for instance, if the nonzero structure is changing
1167: throughout the global iterations.
1169: If the A matrix and B matrix are different you must call MatAssemblyBegin/End() on
1170: each matrix.
1172: Level: beginner
1174: .keywords: SNES, nonlinear, set, Jacobian, matrix
1176: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1177: @*/
1178: PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1179: {
1188: if (func) snes->ops->computejacobian = func;
1189: if (ctx) snes->jacP = ctx;
1190: if (A) {
1191: PetscObjectReference((PetscObject)A);
1192: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1193: snes->jacobian = A;
1194: }
1195: if (B) {
1196: PetscObjectReference((PetscObject)B);
1197: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1198: snes->jacobian_pre = B;
1199: }
1200: return(0);
1201: }
1205: /*@C
1206: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1207: provided context for evaluating the Jacobian.
1209: Not Collective, but Mat object will be parallel if SNES object is
1211: Input Parameter:
1212: . snes - the nonlinear solver context
1214: Output Parameters:
1215: + A - location to stash Jacobian matrix (or PETSC_NULL)
1216: . B - location to stash preconditioner matrix (or PETSC_NULL)
1217: . func - location to put Jacobian function (or PETSC_NULL)
1218: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
1220: Level: advanced
1222: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1223: @*/
1224: PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1225: {
1228: if (A) *A = snes->jacobian;
1229: if (B) *B = snes->jacobian_pre;
1230: if (func) *func = snes->ops->computejacobian;
1231: if (ctx) *ctx = snes->jacP;
1232: return(0);
1233: }
1235: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1236: EXTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
1240: /*@
1241: SNESSetUp - Sets up the internal data structures for the later use
1242: of a nonlinear solver.
1244: Collective on SNES
1246: Input Parameters:
1247: . snes - the SNES context
1249: Notes:
1250: For basic use of the SNES solvers the user need not explicitly call
1251: SNESSetUp(), since these actions will automatically occur during
1252: the call to SNESSolve(). However, if one wishes to control this
1253: phase separately, SNESSetUp() should be called after SNESCreate()
1254: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1256: Level: advanced
1258: .keywords: SNES, nonlinear, setup
1260: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1261: @*/
1262: PetscErrorCode SNESSetUp(SNES snes)
1263: {
1265: PetscTruth flg;
1269: if (snes->setupcalled) return(0);
1271: if (!((PetscObject)snes)->type_name) {
1272: SNESSetType(snes,SNESLS);
1273: }
1275: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator",&flg);
1276: /*
1277: This version replaces the user provided Jacobian matrix with a
1278: matrix-free version but still employs the user-provided preconditioner matrix
1279: */
1280: if (flg) {
1281: Mat J;
1282: MatCreateSNESMF(snes,&J);
1283: MatMFFDSetFromOptions(J);
1284: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1285: SNESSetJacobian(snes,J,0,0,0);
1286: MatDestroy(J);
1287: }
1289: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1290: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator2",&flg);
1291: if (flg) {
1292: Mat J;
1293: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1294: PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");
1295: SNESSetJacobian(snes,J,0,0,0);
1296: MatDestroy(J);
1297: }
1298: #endif
1300: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf",&flg);
1301: /*
1302: This version replaces both the user-provided Jacobian and the user-
1303: provided preconditioner matrix with the default matrix free version.
1304: */
1305: if (flg) {
1306: Mat J;
1307: KSP ksp;
1308: PC pc;
1309: /* create and set matrix-free operator */
1310: MatCreateSNESMF(snes,&J);
1311: MatMFFDSetFromOptions(J);
1312: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1313: SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1314: MatDestroy(J);
1315: /* force no preconditioner */
1316: SNESGetKSP(snes,&ksp);
1317: KSPGetPC(ksp,&pc);
1318: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1319: if (!flg) {
1320: PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");
1321: PCSetType(pc,PCNONE);
1322: }
1323: }
1325: if (!snes->vec_func && !snes->vec_rhs) {
1326: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1327: }
1328: if (!snes->ops->computefunction && !snes->vec_rhs) {
1329: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1330: }
1331: if (snes->vec_func == snes->vec_sol) {
1332: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1333: }
1334:
1335: if (!snes->ksp) {SNESGetKSP(snes, &snes->ksp);}
1336:
1337: if (snes->ops->setup) {
1338: (*snes->ops->setup)(snes);
1339: }
1340: snes->setupcalled = PETSC_TRUE;
1341: return(0);
1342: }
1346: /*@
1347: SNESDestroy - Destroys the nonlinear solver context that was created
1348: with SNESCreate().
1350: Collective on SNES
1352: Input Parameter:
1353: . snes - the SNES context
1355: Level: beginner
1357: .keywords: SNES, nonlinear, destroy
1359: .seealso: SNESCreate(), SNESSolve()
1360: @*/
1361: PetscErrorCode SNESDestroy(SNES snes)
1362: {
1367: if (--((PetscObject)snes)->refct > 0) return(0);
1369: /* if memory was published with AMS then destroy it */
1370: PetscObjectDepublish(snes);
1371: if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1372:
1373: if (snes->vec_rhs) {VecDestroy(snes->vec_rhs);}
1374: if (snes->vec_sol) {VecDestroy(snes->vec_sol);}
1375: if (snes->vec_func) {VecDestroy(snes->vec_func);}
1376: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1377: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1378: if (snes->ksp) {KSPDestroy(snes->ksp);}
1379: PetscFree(snes->kspconvctx);
1380: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1381: SNESMonitorCancel(snes);
1382: if (snes->ops->convergeddestroy) {(*snes->ops->convergeddestroy)(snes->cnvP);}
1383: PetscHeaderDestroy(snes);
1384: return(0);
1385: }
1387: /* ----------- Routines to set solver parameters ---------- */
1391: /*@
1392: SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve.
1394: Collective on SNES
1396: Input Parameters:
1397: + snes - the SNES context
1398: - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1399: the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1401: Options Database Keys:
1402: . -snes_lag_preconditioner <lag>
1404: Notes:
1405: The default is 1
1406: The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1407: If -1 is used before the very first nonlinear solve the preconditioner is still built because there is no previous preconditioner to use
1409: Level: intermediate
1411: .keywords: SNES, nonlinear, set, convergence, tolerances
1413: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagJacobian(), SNESGetLagJacobian()
1415: @*/
1416: PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag)
1417: {
1420: if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1421: if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1422: snes->lagpreconditioner = lag;
1423: return(0);
1424: }
1428: /*@
1429: SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt
1431: Collective on SNES
1433: Input Parameter:
1434: . snes - the SNES context
1435:
1436: Output Parameter:
1437: . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1438: the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that
1440: Options Database Keys:
1441: . -snes_lag_preconditioner <lag>
1443: Notes:
1444: The default is 1
1445: The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1447: Level: intermediate
1449: .keywords: SNES, nonlinear, set, convergence, tolerances
1451: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagPreconditioner()
1453: @*/
1454: PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag)
1455: {
1458: *lag = snes->lagpreconditioner;
1459: return(0);
1460: }
1464: /*@
1465: SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how
1466: often the preconditioner is rebuilt.
1468: Collective on SNES
1470: Input Parameters:
1471: + snes - the SNES context
1472: - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1473: the Jacobian is built etc. -2 means rebuild at next chance but then never again
1475: Options Database Keys:
1476: . -snes_lag_jacobian <lag>
1478: Notes:
1479: The default is 1
1480: The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1481: 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
1482: at the next Newton step but never again (unless it is reset to another value)
1484: Level: intermediate
1486: .keywords: SNES, nonlinear, set, convergence, tolerances
1488: .seealso: SNESSetTrustRegionTolerance(), SNESGetLagPreconditioner(), SNESSetLagPreconditioner(), SNESGetLagJacobian()
1490: @*/
1491: PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag)
1492: {
1495: if (lag < -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater");
1496: if (!lag) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0");
1497: snes->lagjacobian = lag;
1498: return(0);
1499: }
1503: /*@
1504: SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt
1506: Collective on SNES
1508: Input Parameter:
1509: . snes - the SNES context
1510:
1511: Output Parameter:
1512: . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time
1513: the Jacobian is built etc.
1515: Options Database Keys:
1516: . -snes_lag_jacobian <lag>
1518: Notes:
1519: The default is 1
1520: The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1
1522: Level: intermediate
1524: .keywords: SNES, nonlinear, set, convergence, tolerances
1526: .seealso: SNESSetTrustRegionTolerance(), SNESSetLagJacobian(), SNESSetLagPreconditioner(), SNESGetLagPreconditioner()
1528: @*/
1529: PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag)
1530: {
1533: *lag = snes->lagjacobian;
1534: return(0);
1535: }
1539: /*@
1540: SNESSetTolerances - Sets various parameters used in convergence tests.
1542: Collective on SNES
1544: Input Parameters:
1545: + snes - the SNES context
1546: . abstol - absolute convergence tolerance
1547: . rtol - relative convergence tolerance
1548: . stol - convergence tolerance in terms of the norm
1549: of the change in the solution between steps
1550: . maxit - maximum number of iterations
1551: - maxf - maximum number of function evaluations
1553: Options Database Keys:
1554: + -snes_atol <abstol> - Sets abstol
1555: . -snes_rtol <rtol> - Sets rtol
1556: . -snes_stol <stol> - Sets stol
1557: . -snes_max_it <maxit> - Sets maxit
1558: - -snes_max_funcs <maxf> - Sets maxf
1560: Notes:
1561: The default maximum number of iterations is 50.
1562: The default maximum number of function evaluations is 1000.
1564: Level: intermediate
1566: .keywords: SNES, nonlinear, set, convergence, tolerances
1568: .seealso: SNESSetTrustRegionTolerance()
1569: @*/
1570: PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1571: {
1574: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1575: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1576: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1577: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1578: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1579: return(0);
1580: }
1584: /*@
1585: SNESGetTolerances - Gets various parameters used in convergence tests.
1587: Not Collective
1589: Input Parameters:
1590: + snes - the SNES context
1591: . atol - absolute convergence tolerance
1592: . rtol - relative convergence tolerance
1593: . stol - convergence tolerance in terms of the norm
1594: of the change in the solution between steps
1595: . maxit - maximum number of iterations
1596: - maxf - maximum number of function evaluations
1598: Notes:
1599: The user can specify PETSC_NULL for any parameter that is not needed.
1601: Level: intermediate
1603: .keywords: SNES, nonlinear, get, convergence, tolerances
1605: .seealso: SNESSetTolerances()
1606: @*/
1607: PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1608: {
1611: if (atol) *atol = snes->abstol;
1612: if (rtol) *rtol = snes->rtol;
1613: if (stol) *stol = snes->xtol;
1614: if (maxit) *maxit = snes->max_its;
1615: if (maxf) *maxf = snes->max_funcs;
1616: return(0);
1617: }
1621: /*@
1622: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1624: Collective on SNES
1626: Input Parameters:
1627: + snes - the SNES context
1628: - tol - tolerance
1629:
1630: Options Database Key:
1631: . -snes_trtol <tol> - Sets tol
1633: Level: intermediate
1635: .keywords: SNES, nonlinear, set, trust region, tolerance
1637: .seealso: SNESSetTolerances()
1638: @*/
1639: PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1640: {
1643: snes->deltatol = tol;
1644: return(0);
1645: }
1647: /*
1648: Duplicate the lg monitors for SNES from KSP; for some reason with
1649: dynamic libraries things don't work under Sun4 if we just use
1650: macros instead of functions
1651: */
1654: PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1655: {
1660: KSPMonitorLG((KSP)snes,it,norm,ctx);
1661: return(0);
1662: }
1666: PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1667: {
1671: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1672: return(0);
1673: }
1677: PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG draw)
1678: {
1682: KSPMonitorLGDestroy(draw);
1683: return(0);
1684: }
1689: PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx)
1690: {
1691: PetscDrawLG lg;
1692: PetscErrorCode ierr;
1693: PetscReal x,y,per;
1694: PetscViewer v = (PetscViewer)monctx;
1695: static PetscReal prev; /* should be in the context */
1696: PetscDraw draw;
1698: if (!monctx) {
1699: MPI_Comm comm;
1701: PetscObjectGetComm((PetscObject)snes,&comm);
1702: v = PETSC_VIEWER_DRAW_(comm);
1703: }
1704: PetscViewerDrawGetDrawLG(v,0,&lg);
1705: if (!n) {PetscDrawLGReset(lg);}
1706: PetscDrawLGGetDraw(lg,&draw);
1707: PetscDrawSetTitle(draw,"Residual norm");
1708: x = (PetscReal) n;
1709: if (rnorm > 0.0) y = log10(rnorm); else y = -15.0;
1710: PetscDrawLGAddPoint(lg,&x,&y);
1711: if (n < 20 || !(n % 5)) {
1712: PetscDrawLGDraw(lg);
1713: }
1715: PetscViewerDrawGetDrawLG(v,1,&lg);
1716: if (!n) {PetscDrawLGReset(lg);}
1717: PetscDrawLGGetDraw(lg,&draw);
1718: PetscDrawSetTitle(draw,"% elemts > .2*max elemt");
1719: SNESMonitorRange_Private(snes,n,&per);
1720: x = (PetscReal) n;
1721: y = 100.0*per;
1722: PetscDrawLGAddPoint(lg,&x,&y);
1723: if (n < 20 || !(n % 5)) {
1724: PetscDrawLGDraw(lg);
1725: }
1727: PetscViewerDrawGetDrawLG(v,2,&lg);
1728: if (!n) {prev = rnorm;PetscDrawLGReset(lg);}
1729: PetscDrawLGGetDraw(lg,&draw);
1730: PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm");
1731: x = (PetscReal) n;
1732: y = (prev - rnorm)/prev;
1733: PetscDrawLGAddPoint(lg,&x,&y);
1734: if (n < 20 || !(n % 5)) {
1735: PetscDrawLGDraw(lg);
1736: }
1738: PetscViewerDrawGetDrawLG(v,3,&lg);
1739: if (!n) {PetscDrawLGReset(lg);}
1740: PetscDrawLGGetDraw(lg,&draw);
1741: PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)");
1742: x = (PetscReal) n;
1743: y = (prev - rnorm)/(prev*per);
1744: if (n > 2) { /*skip initial crazy value */
1745: PetscDrawLGAddPoint(lg,&x,&y);
1746: }
1747: if (n < 20 || !(n % 5)) {
1748: PetscDrawLGDraw(lg);
1749: }
1750: prev = rnorm;
1751: return(0);
1752: }
1756: PetscErrorCode SNESMonitorLGRangeCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1757: {
1761: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1762: return(0);
1763: }
1767: PetscErrorCode SNESMonitorLGRangeDestroy(PetscDrawLG draw)
1768: {
1772: KSPMonitorLGDestroy(draw);
1773: return(0);
1774: }
1776: /* ------------ Routines to set performance monitoring options ----------- */
1780: /*@C
1781: SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1782: iteration of the nonlinear solver to display the iteration's
1783: progress.
1785: Collective on SNES
1787: Input Parameters:
1788: + snes - the SNES context
1789: . func - monitoring routine
1790: . mctx - [optional] user-defined context for private data for the
1791: monitor routine (use PETSC_NULL if no context is desired)
1792: - monitordestroy - [optional] routine that frees monitor context
1793: (may be PETSC_NULL)
1795: Calling sequence of func:
1796: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1798: + snes - the SNES context
1799: . its - iteration number
1800: . norm - 2-norm function value (may be estimated)
1801: - mctx - [optional] monitoring context
1803: Options Database Keys:
1804: + -snes_monitor - sets SNESMonitorDefault()
1805: . -snes_monitor_draw - sets line graph monitor,
1806: uses SNESMonitorLGCreate()
1807: _ -snes_monitor_cancel - cancels all monitors that have
1808: been hardwired into a code by
1809: calls to SNESMonitorSet(), but
1810: does not cancel those set via
1811: the options database.
1813: Notes:
1814: Several different monitoring routines may be set by calling
1815: SNESMonitorSet() multiple times; all will be called in the
1816: order in which they were set.
1818: Fortran notes: Only a single monitor function can be set for each SNES object
1820: Level: intermediate
1822: .keywords: SNES, nonlinear, set, monitor
1824: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1825: @*/
1826: PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1827: {
1828: PetscInt i;
1832: if (snes->numbermonitors >= MAXSNESMONITORS) {
1833: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1834: }
1835: for (i=0; i<snes->numbermonitors;i++) {
1836: if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);
1838: /* check if both default monitors that share common ASCII viewer */
1839: if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1840: if (mctx && snes->monitorcontext[i]) {
1841: PetscErrorCode ierr;
1842: PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1843: PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1844: if (viewer1->viewer == viewer2->viewer) {
1845: (*monitordestroy)(mctx);
1846: return(0);
1847: }
1848: }
1849: }
1850: }
1851: snes->monitor[snes->numbermonitors] = monitor;
1852: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1853: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1854: return(0);
1855: }
1859: /*@C
1860: SNESMonitorCancel - Clears all the monitor functions for a SNES object.
1862: Collective on SNES
1864: Input Parameters:
1865: . snes - the SNES context
1867: Options Database Key:
1868: . -snes_monitor_cancel - cancels all monitors that have been hardwired
1869: into a code by calls to SNESMonitorSet(), but does not cancel those
1870: set via the options database
1872: Notes:
1873: There is no way to clear one specific monitor from a SNES object.
1875: Level: intermediate
1877: .keywords: SNES, nonlinear, set, monitor
1879: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1880: @*/
1881: PetscErrorCode SNESMonitorCancel(SNES snes)
1882: {
1884: PetscInt i;
1888: for (i=0; i<snes->numbermonitors; i++) {
1889: if (snes->monitordestroy[i]) {
1890: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1891: }
1892: }
1893: snes->numbermonitors = 0;
1894: return(0);
1895: }
1899: /*@C
1900: SNESSetConvergenceTest - Sets the function that is to be used
1901: to test for convergence of the nonlinear iterative solution.
1903: Collective on SNES
1905: Input Parameters:
1906: + snes - the SNES context
1907: . func - routine to test for convergence
1908: . cctx - [optional] context for private data for the convergence routine (may be PETSC_NULL)
1909: - destroy - [optional] destructor for the context (may be PETSC_NULL; PETSC_NULL_FUNCTION in Fortran)
1911: Calling sequence of func:
1912: $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1914: + snes - the SNES context
1915: . it - current iteration (0 is the first and is before any Newton step)
1916: . cctx - [optional] convergence context
1917: . reason - reason for convergence/divergence
1918: . xnorm - 2-norm of current iterate
1919: . gnorm - 2-norm of current step
1920: - f - 2-norm of function
1922: Level: advanced
1924: .keywords: SNES, nonlinear, set, convergence, test
1926: .seealso: SNESDefaultConverged(), SNESSkipConverged()
1927: @*/
1928: PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*))
1929: {
1934: if (!func) func = SNESSkipConverged;
1935: if (snes->ops->convergeddestroy) {
1936: (*snes->ops->convergeddestroy)(snes->cnvP);
1937: }
1938: snes->ops->converged = func;
1939: snes->ops->convergeddestroy = destroy;
1940: snes->cnvP = cctx;
1941: return(0);
1942: }
1946: /*@
1947: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1949: Not Collective
1951: Input Parameter:
1952: . snes - the SNES context
1954: Output Parameter:
1955: . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the
1956: manual pages for the individual convergence tests for complete lists
1958: Level: intermediate
1960: Notes: Can only be called after the call the SNESSolve() is complete.
1962: .keywords: SNES, nonlinear, set, convergence, test
1964: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1965: @*/
1966: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1967: {
1971: *reason = snes->reason;
1972: return(0);
1973: }
1977: /*@
1978: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1980: Collective on SNES
1982: Input Parameters:
1983: + snes - iterative context obtained from SNESCreate()
1984: . a - array to hold history
1985: . its - integer array holds the number of linear iterations for each solve.
1986: . na - size of a and its
1987: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1988: else it continues storing new values for new nonlinear solves after the old ones
1990: Notes:
1991: If set, this array will contain the function norms computed
1992: at each step.
1994: This routine is useful, e.g., when running a code for purposes
1995: of accurate performance monitoring, when no I/O should be done
1996: during the section of code that is being timed.
1998: Level: intermediate
2000: .keywords: SNES, set, convergence, history
2002: .seealso: SNESGetConvergenceHistory()
2004: @*/
2005: PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
2006: {
2011: snes->conv_hist = a;
2012: snes->conv_hist_its = its;
2013: snes->conv_hist_max = na;
2014: snes->conv_hist_len = 0;
2015: snes->conv_hist_reset = reset;
2016: return(0);
2017: }
2021: /*@C
2022: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
2024: Collective on SNES
2026: Input Parameter:
2027: . snes - iterative context obtained from SNESCreate()
2029: Output Parameters:
2030: . a - array to hold history
2031: . its - integer array holds the number of linear iterations (or
2032: negative if not converged) for each solve.
2033: - na - size of a and its
2035: Notes:
2036: The calling sequence for this routine in Fortran is
2037: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
2039: This routine is useful, e.g., when running a code for purposes
2040: of accurate performance monitoring, when no I/O should be done
2041: during the section of code that is being timed.
2043: Level: intermediate
2045: .keywords: SNES, get, convergence, history
2047: .seealso: SNESSetConvergencHistory()
2049: @*/
2050: PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
2051: {
2054: if (a) *a = snes->conv_hist;
2055: if (its) *its = snes->conv_hist_its;
2056: if (na) *na = snes->conv_hist_len;
2057: return(0);
2058: }
2062: /*@C
2063: SNESSetUpdate - Sets the general-purpose update function called
2064: at the beginning o every iteration of the nonlinear solve. Specifically
2065: it is called just before the Jacobian is "evaluated".
2067: Collective on SNES
2069: Input Parameters:
2070: . snes - The nonlinear solver context
2071: . func - The function
2073: Calling sequence of func:
2074: . func (SNES snes, PetscInt step);
2076: . step - The current step of the iteration
2078: Level: intermediate
2080: .keywords: SNES, update
2082: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
2083: @*/
2084: PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
2085: {
2088: snes->ops->update = func;
2089: return(0);
2090: }
2094: /*@
2095: SNESDefaultUpdate - The default update function which does nothing.
2097: Not collective
2099: Input Parameters:
2100: . snes - The nonlinear solver context
2101: . step - The current step of the iteration
2103: Level: intermediate
2105: .keywords: SNES, update
2106: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
2107: @*/
2108: PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step)
2109: {
2111: return(0);
2112: }
2116: /*
2117: SNESScaleStep_Private - Scales a step so that its length is less than the
2118: positive parameter delta.
2120: Input Parameters:
2121: + snes - the SNES context
2122: . y - approximate solution of linear system
2123: . fnorm - 2-norm of current function
2124: - delta - trust region size
2126: Output Parameters:
2127: + gpnorm - predicted function norm at the new point, assuming local
2128: linearization. The value is zero if the step lies within the trust
2129: region, and exceeds zero otherwise.
2130: - ynorm - 2-norm of the step
2132: Note:
2133: For non-trust region methods such as SNESLS, the parameter delta
2134: is set to be the maximum allowable step size.
2136: .keywords: SNES, nonlinear, scale, step
2137: */
2138: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
2139: {
2140: PetscReal nrm;
2141: PetscScalar cnorm;
2149: VecNorm(y,NORM_2,&nrm);
2150: if (nrm > *delta) {
2151: nrm = *delta/nrm;
2152: *gpnorm = (1.0 - nrm)*(*fnorm);
2153: cnorm = nrm;
2154: VecScale(y,cnorm);
2155: *ynorm = *delta;
2156: } else {
2157: *gpnorm = 0.0;
2158: *ynorm = nrm;
2159: }
2160: return(0);
2161: }
2165: /*@C
2166: SNESSolve - Solves a nonlinear system F(x) = b.
2167: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
2169: Collective on SNES
2171: Input Parameters:
2172: + snes - the SNES context
2173: . b - the constant part of the equation, or PETSC_NULL to use zero.
2174: - x - the solution vector.
2176: Notes:
2177: The user should initialize the vector,x, with the initial guess
2178: for the nonlinear solve prior to calling SNESSolve. In particular,
2179: to employ an initial guess of zero, the user should explicitly set
2180: this vector to zero by calling VecSet().
2182: Level: beginner
2184: .keywords: SNES, nonlinear, solve
2186: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
2187: @*/
2188: PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x)
2189: {
2191: PetscTruth flg;
2192: char filename[PETSC_MAX_PATH_LEN];
2193: PetscViewer viewer;
2202: /* set solution vector */
2203: PetscObjectReference((PetscObject)x);
2204: if (snes->vec_sol) { VecDestroy(snes->vec_sol); }
2205: snes->vec_sol = x;
2206: /* set afine vector if provided */
2207: if (b) { PetscObjectReference((PetscObject)b); }
2208: if (snes->vec_rhs) { VecDestroy(snes->vec_rhs); }
2209: snes->vec_rhs = b;
2210:
2211: if (!snes->vec_func && snes->vec_rhs) {
2212: VecDuplicate(b, &snes->vec_func);
2213: }
2215: SNESSetUp(snes);
2217: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
2218: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
2220: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
2221: (*snes->ops->solve)(snes);
2222: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
2223: if (snes->domainerror){
2224: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
2225: snes->domainerror = PETSC_FALSE;
2226: }
2228: if (!snes->reason) {
2229: SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
2230: }
2231:
2232: PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
2233: if (flg && !PetscPreLoadingOn) {
2234: PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
2235: SNESView(snes,viewer);
2236: PetscViewerDestroy(viewer);
2237: }
2239: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);
2240: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
2241: if (snes->printreason) {
2242: if (snes->reason > 0) {
2243: PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
2244: } else {
2245: PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
2246: }
2247: }
2249: return(0);
2250: }
2252: /* --------- Internal routines for SNES Package --------- */
2256: /*@C
2257: SNESSetType - Sets the method for the nonlinear solver.
2259: Collective on SNES
2261: Input Parameters:
2262: + snes - the SNES context
2263: - type - a known method
2265: Options Database Key:
2266: . -snes_type <type> - Sets the method; use -help for a list
2267: of available methods (for instance, ls or tr)
2269: Notes:
2270: See "petsc/include/petscsnes.h" for available methods (for instance)
2271: + SNESLS - Newton's method with line search
2272: (systems of nonlinear equations)
2273: . SNESTR - Newton's method with trust region
2274: (systems of nonlinear equations)
2276: Normally, it is best to use the SNESSetFromOptions() command and then
2277: set the SNES solver type from the options database rather than by using
2278: this routine. Using the options database provides the user with
2279: maximum flexibility in evaluating the many nonlinear solvers.
2280: The SNESSetType() routine is provided for those situations where it
2281: is necessary to set the nonlinear solver independently of the command
2282: line or options database. This might be the case, for example, when
2283: the choice of solver changes during the execution of the program,
2284: and the user's application is taking responsibility for choosing the
2285: appropriate method.
2287: Level: intermediate
2289: .keywords: SNES, set, type
2291: .seealso: SNESType, SNESCreate()
2293: @*/
2294: PetscErrorCode SNESSetType(SNES snes,const SNESType type)
2295: {
2296: PetscErrorCode ierr,(*r)(SNES);
2297: PetscTruth match;
2303: PetscTypeCompare((PetscObject)snes,type,&match);
2304: if (match) return(0);
2306: PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);
2307: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
2308: /* Destroy the previous private SNES context */
2309: if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
2310: /* Reinitialize function pointers in SNESOps structure */
2311: snes->ops->setup = 0;
2312: snes->ops->solve = 0;
2313: snes->ops->view = 0;
2314: snes->ops->setfromoptions = 0;
2315: snes->ops->destroy = 0;
2316: /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
2317: snes->setupcalled = PETSC_FALSE;
2318: (*r)(snes);
2319: PetscObjectChangeTypeName((PetscObject)snes,type);
2320: return(0);
2321: }
2324: /* --------------------------------------------------------------------- */
2327: /*@
2328: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2329: registered by SNESRegisterDynamic().
2331: Not Collective
2333: Level: advanced
2335: .keywords: SNES, nonlinear, register, destroy
2337: .seealso: SNESRegisterAll(), SNESRegisterAll()
2338: @*/
2339: PetscErrorCode SNESRegisterDestroy(void)
2340: {
2344: PetscFListDestroy(&SNESList);
2345: SNESRegisterAllCalled = PETSC_FALSE;
2346: return(0);
2347: }
2351: /*@C
2352: SNESGetType - Gets the SNES method type and name (as a string).
2354: Not Collective
2356: Input Parameter:
2357: . snes - nonlinear solver context
2359: Output Parameter:
2360: . type - SNES method (a character string)
2362: Level: intermediate
2364: .keywords: SNES, nonlinear, get, type, name
2365: @*/
2366: PetscErrorCode SNESGetType(SNES snes,const SNESType *type)
2367: {
2371: *type = ((PetscObject)snes)->type_name;
2372: return(0);
2373: }
2377: /*@
2378: SNESGetSolution - Returns the vector where the approximate solution is
2379: stored.
2381: Not Collective, but Vec is parallel if SNES is parallel
2383: Input Parameter:
2384: . snes - the SNES context
2386: Output Parameter:
2387: . x - the solution
2389: Level: intermediate
2391: .keywords: SNES, nonlinear, get, solution
2393: .seealso: SNESGetSolutionUpdate(), SNESGetFunction()
2394: @*/
2395: PetscErrorCode SNESGetSolution(SNES snes,Vec *x)
2396: {
2400: *x = snes->vec_sol;
2401: return(0);
2402: }
2406: /*@
2407: SNESGetSolutionUpdate - Returns the vector where the solution update is
2408: stored.
2410: Not Collective, but Vec is parallel if SNES is parallel
2412: Input Parameter:
2413: . snes - the SNES context
2415: Output Parameter:
2416: . x - the solution update
2418: Level: advanced
2420: .keywords: SNES, nonlinear, get, solution, update
2422: .seealso: SNESGetSolution(), SNESGetFunction()
2423: @*/
2424: PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x)
2425: {
2429: *x = snes->vec_sol_update;
2430: return(0);
2431: }
2435: /*@C
2436: SNESGetFunction - Returns the vector where the function is stored.
2438: Not Collective, but Vec is parallel if SNES is parallel
2440: Input Parameter:
2441: . snes - the SNES context
2443: Output Parameter:
2444: + r - the function (or PETSC_NULL)
2445: . func - the function (or PETSC_NULL)
2446: - ctx - the function context (or PETSC_NULL)
2448: Level: advanced
2450: .keywords: SNES, nonlinear, get, function
2452: .seealso: SNESSetFunction(), SNESGetSolution()
2453: @*/
2454: PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2455: {
2458: if (r) *r = snes->vec_func;
2459: if (func) *func = snes->ops->computefunction;
2460: if (ctx) *ctx = snes->funP;
2461: return(0);
2462: }
2466: /*@C
2467: SNESSetOptionsPrefix - Sets the prefix used for searching for all
2468: SNES options in the database.
2470: Collective on SNES
2472: Input Parameter:
2473: + snes - the SNES context
2474: - prefix - the prefix to prepend to all option names
2476: Notes:
2477: A hyphen (-) must NOT be given at the beginning of the prefix name.
2478: The first character of all runtime options is AUTOMATICALLY the hyphen.
2480: Level: advanced
2482: .keywords: SNES, set, options, prefix, database
2484: .seealso: SNESSetFromOptions()
2485: @*/
2486: PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[])
2487: {
2492: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2493: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2494: KSPSetOptionsPrefix(snes->ksp,prefix);
2495: return(0);
2496: }
2500: /*@C
2501: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2502: SNES options in the database.
2504: Collective on SNES
2506: Input Parameters:
2507: + snes - the SNES context
2508: - prefix - the prefix to prepend to all option names
2510: Notes:
2511: A hyphen (-) must NOT be given at the beginning of the prefix name.
2512: The first character of all runtime options is AUTOMATICALLY the hyphen.
2514: Level: advanced
2516: .keywords: SNES, append, options, prefix, database
2518: .seealso: SNESGetOptionsPrefix()
2519: @*/
2520: PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2521: {
2523:
2526: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2527: if (!snes->ksp) {SNESGetKSP(snes,&snes->ksp);}
2528: KSPAppendOptionsPrefix(snes->ksp,prefix);
2529: return(0);
2530: }
2534: /*@C
2535: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2536: SNES options in the database.
2538: Not Collective
2540: Input Parameter:
2541: . snes - the SNES context
2543: Output Parameter:
2544: . prefix - pointer to the prefix string used
2546: Notes: On the fortran side, the user should pass in a string 'prefix' of
2547: sufficient length to hold the prefix.
2549: Level: advanced
2551: .keywords: SNES, get, options, prefix, database
2553: .seealso: SNESAppendOptionsPrefix()
2554: @*/
2555: PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2556: {
2561: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2562: return(0);
2563: }
2568: /*@C
2569: SNESRegister - See SNESRegisterDynamic()
2571: Level: advanced
2572: @*/
2573: PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2574: {
2575: char fullname[PETSC_MAX_PATH_LEN];
2579: PetscFListConcat(path,name,fullname);
2580: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2581: return(0);
2582: }
2586: PetscErrorCode SNESTestLocalMin(SNES snes)
2587: {
2589: PetscInt N,i,j;
2590: Vec u,uh,fh;
2591: PetscScalar value;
2592: PetscReal norm;
2595: SNESGetSolution(snes,&u);
2596: VecDuplicate(u,&uh);
2597: VecDuplicate(u,&fh);
2599: /* currently only works for sequential */
2600: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2601: VecGetSize(u,&N);
2602: for (i=0; i<N; i++) {
2603: VecCopy(u,uh);
2604: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2605: for (j=-10; j<11; j++) {
2606: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2607: VecSetValue(uh,i,value,ADD_VALUES);
2608: SNESComputeFunction(snes,uh,fh);
2609: VecNorm(fh,NORM_2,&norm);
2610: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2611: value = -value;
2612: VecSetValue(uh,i,value,ADD_VALUES);
2613: }
2614: }
2615: VecDestroy(uh);
2616: VecDestroy(fh);
2617: return(0);
2618: }
2622: /*@
2623: SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2624: computing relative tolerance for linear solvers within an inexact
2625: Newton method.
2627: Collective on SNES
2629: Input Parameters:
2630: + snes - SNES context
2631: - flag - PETSC_TRUE or PETSC_FALSE
2633: Notes:
2634: Currently, the default is to use a constant relative tolerance for
2635: the inner linear solvers. Alternatively, one can use the
2636: Eisenstat-Walker method, where the relative convergence tolerance
2637: is reset at each Newton iteration according progress of the nonlinear
2638: solver.
2640: Level: advanced
2642: Reference:
2643: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2644: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2646: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2648: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2649: @*/
2650: PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2651: {
2654: snes->ksp_ewconv = flag;
2655: return(0);
2656: }
2660: /*@
2661: SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2662: for computing relative tolerance for linear solvers within an
2663: inexact Newton method.
2665: Not Collective
2667: Input Parameter:
2668: . snes - SNES context
2670: Output Parameter:
2671: . flag - PETSC_TRUE or PETSC_FALSE
2673: Notes:
2674: Currently, the default is to use a constant relative tolerance for
2675: the inner linear solvers. Alternatively, one can use the
2676: Eisenstat-Walker method, where the relative convergence tolerance
2677: is reset at each Newton iteration according progress of the nonlinear
2678: solver.
2680: Level: advanced
2682: Reference:
2683: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2684: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2686: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2688: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2689: @*/
2690: PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2691: {
2695: *flag = snes->ksp_ewconv;
2696: return(0);
2697: }
2701: /*@
2702: SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2703: convergence criteria for the linear solvers within an inexact
2704: Newton method.
2706: Collective on SNES
2707:
2708: Input Parameters:
2709: + snes - SNES context
2710: . version - version 1, 2 (default is 2) or 3
2711: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2712: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2713: . gamma - multiplicative factor for version 2 rtol computation
2714: (0 <= gamma2 <= 1)
2715: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2716: . alpha2 - power for safeguard
2717: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2719: Note:
2720: Version 3 was contributed by Luis Chacon, June 2006.
2722: Use PETSC_DEFAULT to retain the default for any of the parameters.
2724: Level: advanced
2726: Reference:
2727: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2728: inexact Newton method", Utah State University Math. Stat. Dept. Res.
2729: Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
2731: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
2733: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2734: @*/
2735: PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2736: PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2737: {
2738: SNESKSPEW *kctx;
2741: kctx = (SNESKSPEW*)snes->kspconvctx;
2742: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2744: if (version != PETSC_DEFAULT) kctx->version = version;
2745: if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
2746: if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max;
2747: if (gamma != PETSC_DEFAULT) kctx->gamma = gamma;
2748: if (alpha != PETSC_DEFAULT) kctx->alpha = alpha;
2749: if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2;
2750: if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2751:
2752: if (kctx->version < 1 || kctx->version > 3) {
2753: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2754: }
2755: if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2756: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2757: }
2758: if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2759: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2760: }
2761: if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2762: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2763: }
2764: if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2765: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2766: }
2767: if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2768: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2769: }
2770: return(0);
2771: }
2775: /*@
2776: SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2777: convergence criteria for the linear solvers within an inexact
2778: Newton method.
2780: Not Collective
2781:
2782: Input Parameters:
2783: snes - SNES context
2785: Output Parameters:
2786: + version - version 1, 2 (default is 2) or 3
2787: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2788: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2789: . gamma - multiplicative factor for version 2 rtol computation
2790: (0 <= gamma2 <= 1)
2791: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2792: . alpha2 - power for safeguard
2793: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2795: Level: advanced
2797: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
2799: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2800: @*/
2801: PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2802: PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2803: {
2804: SNESKSPEW *kctx;
2807: kctx = (SNESKSPEW*)snes->kspconvctx;
2808: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2809: if(version) *version = kctx->version;
2810: if(rtol_0) *rtol_0 = kctx->rtol_0;
2811: if(rtol_max) *rtol_max = kctx->rtol_max;
2812: if(gamma) *gamma = kctx->gamma;
2813: if(alpha) *alpha = kctx->alpha;
2814: if(alpha2) *alpha2 = kctx->alpha2;
2815: if(threshold) *threshold = kctx->threshold;
2816: return(0);
2817: }
2821: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2822: {
2824: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2825: PetscReal rtol=PETSC_DEFAULT,stol;
2828: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2829: if (!snes->iter) { /* first time in, so use the original user rtol */
2830: rtol = kctx->rtol_0;
2831: } else {
2832: if (kctx->version == 1) {
2833: rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2834: if (rtol < 0.0) rtol = -rtol;
2835: stol = pow(kctx->rtol_last,kctx->alpha2);
2836: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2837: } else if (kctx->version == 2) {
2838: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2839: stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2840: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2841: } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2842: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2843: /* safeguard: avoid sharp decrease of rtol */
2844: stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2845: stol = PetscMax(rtol,stol);
2846: rtol = PetscMin(kctx->rtol_0,stol);
2847: /* safeguard: avoid oversolving */
2848: stol = kctx->gamma*(snes->ttol)/snes->norm;
2849: stol = PetscMax(rtol,stol);
2850: rtol = PetscMin(kctx->rtol_0,stol);
2851: } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2852: }
2853: /* safeguard: avoid rtol greater than one */
2854: rtol = PetscMin(rtol,kctx->rtol_max);
2855: KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2856: PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2857: return(0);
2858: }
2862: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2863: {
2865: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2866: PCSide pcside;
2867: Vec lres;
2870: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2871: KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2872: SNESGetFunctionNorm(snes,&kctx->norm_last);
2873: if (kctx->version == 1) {
2874: KSPGetPreconditionerSide(ksp,&pcside);
2875: if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2876: /* KSP residual is true linear residual */
2877: KSPGetResidualNorm(ksp,&kctx->lresid_last);
2878: } else {
2879: /* KSP residual is preconditioned residual */
2880: /* compute true linear residual norm */
2881: VecDuplicate(b,&lres);
2882: MatMult(snes->jacobian,x,lres);
2883: VecAYPX(lres,-1.0,b);
2884: VecNorm(lres,NORM_2,&kctx->lresid_last);
2885: VecDestroy(lres);
2886: }
2887: }
2888: return(0);
2889: }
2893: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2894: {
2898: if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x); }
2899: KSPSolve(ksp,b,x);
2900: if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2901: return(0);
2902: }