Actual source code: snes.c
1: #define PETSCSNES_DLL
3: #include include/private/snesimpl.h
5: PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
6: PetscFList SNESList = PETSC_NULL;
8: /* Logging support */
9: PetscCookie SNES_COOKIE = 0;
10: PetscEvent SNES_Solve = 0, SNES_LineSearch = 0, SNES_FunctionEval = 0, SNES_JacobianEval = 0;
14: /*@C
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: 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_trtol <trtol> - trust region tolerance
179: . -snes_no_convergence_test - skip convergence test in nonlinear
180: solver; hence iterations will continue until max_it
181: or some other criterion is reached. Saves expense
182: of convergence test
183: . -snes_monitor <optional filename> - prints residual norm at each iteration. if no
184: filename given prints to stdout
185: . -snes_monitor_solution - plots solution at each iteration
186: . -snes_monitor_residual - plots residual (not its norm) at each iteration
187: . -snes_monitor_solution_update - plots update to solution at each iteration
188: . -snes_monitor_draw - plots residual norm at each iteration
189: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
190: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
191: - -snes_converged_reason - print the reason for convergence/divergence after each solve
193: Options Database for Eisenstat-Walker method:
194: + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
195: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
196: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
197: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
198: . -snes_ksp_ew_gamma <gamma> - Sets gamma
199: . -snes_ksp_ew_alpha <alpha> - Sets alpha
200: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
201: - -snes_ksp_ew_threshold <threshold> - Sets threshold
203: Notes:
204: To see all options, run your program with the -help option or consult
205: the users manual.
207: Level: beginner
209: .keywords: SNES, nonlinear, set, options, database
211: .seealso: SNESSetOptionsPrefix()
212: @*/
213: PetscErrorCode SNESSetFromOptions(SNES snes)
214: {
215: PetscTruth flg;
216: PetscInt i,indx;
217: const char *deft = SNESLS;
218: const char *convtests[] = {"default","skip"};
219: SNESKSPEW *kctx = NULL;
220: char type[256], monfilename[PETSC_MAX_PATH_LEN];
221: PetscViewerASCIIMonitor monviewer;
222: PetscErrorCode ierr;
227: PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");
228: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
229: if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
230: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
231: if (flg) {
232: SNESSetType(snes,type);
233: } else if (!((PetscObject)snes)->type_name) {
234: SNESSetType(snes,deft);
235: }
236: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
238: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
239: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);
241: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
242: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
243: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
244: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
246: PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
247: if (flg) {
248: switch (indx) {
249: case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL); break;
250: case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL); break;
251: }
252: }
254: PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
255: if (flg) {
256: snes->printreason = PETSC_TRUE;
257: }
259: kctx = (SNESKSPEW *)snes->kspconvctx;
261: PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
263: PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
264: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
265: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
266: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
267: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
268: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
269: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);
271: PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);
272: if (flg) {SNESMonitorCancel(snes);}
274: PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
275: if (flg) {
276: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
277: SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
278: }
280: PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
281: if (flg) {
282: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
283: SNESMonitorSetRatio(snes,monviewer);
284: }
286: PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
287: if (flg) {
288: PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
289: SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
290: }
292: PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);
293: if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
294: PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);
295: if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
296: PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);
297: if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
298: PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);
299: if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
301: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
302: if (flg) {
303: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
304: PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
305: }
307: for(i = 0; i < numberofsetfromoptions; i++) {
308: (*othersetfromoptions[i])(snes);
309: }
311: if (snes->ops->setfromoptions) {
312: (*snes->ops->setfromoptions)(snes);
313: }
314: PetscOptionsEnd();
316: KSPSetFromOptions(snes->ksp);
318: return(0);
319: }
324: /*@
325: SNESSetApplicationContext - Sets the optional user-defined context for
326: the nonlinear solvers.
328: Collective on SNES
330: Input Parameters:
331: + snes - the SNES context
332: - usrP - optional user context
334: Level: intermediate
336: .keywords: SNES, nonlinear, set, application, context
338: .seealso: SNESGetApplicationContext()
339: @*/
340: PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP)
341: {
344: snes->user = usrP;
345: return(0);
346: }
350: /*@C
351: SNESGetApplicationContext - Gets the user-defined context for the
352: nonlinear solvers.
354: Not Collective
356: Input Parameter:
357: . snes - SNES context
359: Output Parameter:
360: . usrP - user context
362: Level: intermediate
364: .keywords: SNES, nonlinear, get, application, context
366: .seealso: SNESSetApplicationContext()
367: @*/
368: PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP)
369: {
372: *usrP = snes->user;
373: return(0);
374: }
378: /*@
379: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
380: at this time.
382: Not Collective
384: Input Parameter:
385: . snes - SNES context
387: Output Parameter:
388: . iter - iteration number
390: Notes:
391: For example, during the computation of iteration 2 this would return 1.
393: This is useful for using lagged Jacobians (where one does not recompute the
394: Jacobian at each SNES iteration). For example, the code
395: .vb
396: SNESGetIterationNumber(snes,&it);
397: if (!(it % 2)) {
398: [compute Jacobian here]
399: }
400: .ve
401: can be used in your ComputeJacobian() function to cause the Jacobian to be
402: recomputed every second SNES iteration.
404: Level: intermediate
406: .keywords: SNES, nonlinear, get, iteration, number,
408: .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
409: @*/
410: PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter)
411: {
415: *iter = snes->iter;
416: return(0);
417: }
421: /*@
422: SNESGetFunctionNorm - Gets the norm of the current function that was set
423: with SNESSSetFunction().
425: Collective on SNES
427: Input Parameter:
428: . snes - SNES context
430: Output Parameter:
431: . fnorm - 2-norm of function
433: Level: intermediate
435: .keywords: SNES, nonlinear, get, function, norm
437: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
438: @*/
439: PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
440: {
444: *fnorm = snes->norm;
445: return(0);
446: }
450: /*@
451: SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
452: attempted by the nonlinear solver.
454: Not Collective
456: Input Parameter:
457: . snes - SNES context
459: Output Parameter:
460: . nfails - number of unsuccessful steps attempted
462: Notes:
463: This counter is reset to zero for each successive call to SNESSolve().
465: Level: intermediate
467: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
469: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
470: SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
471: @*/
472: PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
473: {
477: *nfails = snes->numFailures;
478: return(0);
479: }
483: /*@
484: SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
485: attempted by the nonlinear solver before it gives up.
487: Not Collective
489: Input Parameters:
490: + snes - SNES context
491: - maxFails - maximum of unsuccessful steps
493: Level: intermediate
495: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
497: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
498: SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
499: @*/
500: PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
501: {
504: snes->maxFailures = maxFails;
505: return(0);
506: }
510: /*@
511: SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
512: attempted by the nonlinear solver before it gives up.
514: Not Collective
516: Input Parameter:
517: . snes - SNES context
519: Output Parameter:
520: . maxFails - maximum of unsuccessful steps
522: Level: intermediate
524: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
526: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
527: SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
528:
529: @*/
530: PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
531: {
535: *maxFails = snes->maxFailures;
536: return(0);
537: }
541: /*@
542: SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
543: done by SNES.
545: Not Collective
547: Input Parameter:
548: . snes - SNES context
550: Output Parameter:
551: . nfuncs - number of evaluations
553: Level: intermediate
555: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
557: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
558: @*/
559: PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
560: {
564: *nfuncs = snes->nfuncs;
565: return(0);
566: }
570: /*@
571: SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
572: linear solvers.
574: Not Collective
576: Input Parameter:
577: . snes - SNES context
579: Output Parameter:
580: . nfails - number of failed solves
582: Notes:
583: This counter is reset to zero for each successive call to SNESSolve().
585: Level: intermediate
587: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
589: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures()
590: @*/
591: PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
592: {
596: *nfails = snes->numLinearSolveFailures;
597: return(0);
598: }
602: /*@
603: SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
604: allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
606: Collective on SNES
608: Input Parameters:
609: + snes - SNES context
610: - maxFails - maximum allowed linear solve failures
612: Level: intermediate
614: Notes: By default this is 1; that is SNES returns on the first failed linear solve
616: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
618: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
619: @*/
620: PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
621: {
624: snes->maxLinearSolveFailures = maxFails;
625: return(0);
626: }
630: /*@
631: SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
632: are allowed before SNES terminates
634: Not Collective
636: Input Parameter:
637: . snes - SNES context
639: Output Parameter:
640: . maxFails - maximum of unsuccessful solves allowed
642: Level: intermediate
644: Notes: By default this is 1; that is SNES returns on the first failed linear solve
646: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
648: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(),
649: @*/
650: PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
651: {
655: *maxFails = snes->maxLinearSolveFailures;
656: return(0);
657: }
661: /*@
662: SNESGetLinearSolveIterations - Gets the total number of linear iterations
663: used by the nonlinear solver.
665: Not Collective
667: Input Parameter:
668: . snes - SNES context
670: Output Parameter:
671: . lits - number of linear iterations
673: Notes:
674: This counter is reset to zero for each successive call to SNESSolve().
676: Level: intermediate
678: .keywords: SNES, nonlinear, get, number, linear, iterations
680: .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm()S, NESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
681: @*/
682: PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
683: {
687: *lits = snes->linear_its;
688: return(0);
689: }
693: /*@
694: SNESGetKSP - Returns the KSP context for a SNES solver.
696: Not Collective, but if SNES object is parallel, then KSP object is parallel
698: Input Parameter:
699: . snes - the SNES context
701: Output Parameter:
702: . ksp - the KSP context
704: Notes:
705: The user can then directly manipulate the KSP context to set various
706: options, etc. Likewise, the user can then extract and manipulate the
707: PC contexts as well.
709: Level: beginner
711: .keywords: SNES, nonlinear, get, KSP, context
713: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
714: @*/
715: PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp)
716: {
720: *ksp = snes->ksp;
721: return(0);
722: }
726: /*@
727: SNESSetKSP - Sets a KSP context for the SNES object to use
729: Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
731: Input Parameters:
732: + snes - the SNES context
733: - ksp - the KSP context
735: Notes:
736: The SNES object already has its KSP object, you can obtain with SNESGetKSP()
737: so this routine is rarely needed.
739: The KSP object that is already in the SNES object has its reference count
740: decreased by one.
742: Level: developer
744: .keywords: SNES, nonlinear, get, KSP, context
746: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
747: @*/
748: PetscErrorCode SNESSetKSP(SNES snes,KSP ksp)
749: {
756: PetscObjectReference((PetscObject)ksp);
757: if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
758: snes->ksp = ksp;
759: return(0);
760: }
762: #if 0
765: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
766: {
768: return(0);
769: }
770: #endif
772: /* -----------------------------------------------------------*/
775: /*@
776: SNESCreate - Creates a nonlinear solver context.
778: Collective on MPI_Comm
780: Input Parameters:
781: . comm - MPI communicator
783: Output Parameter:
784: . outsnes - the new SNES context
786: Options Database Keys:
787: + -snes_mf - Activates default matrix-free Jacobian-vector products,
788: and no preconditioning matrix
789: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
790: products, and a user-provided preconditioning matrix
791: as set by SNESSetJacobian()
792: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
794: Level: beginner
796: .keywords: SNES, nonlinear, create, context
798: .seealso: SNESSolve(), SNESDestroy(), SNES
799: @*/
800: PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes)
801: {
802: PetscErrorCode ierr;
803: SNES snes;
804: SNESKSPEW *kctx;
808: *outsnes = PETSC_NULL;
809: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
810: SNESInitializePackage(PETSC_NULL);
811: #endif
813: PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
815: snes->ops->converged = SNESDefaultConverged;
816: snes->max_its = 50;
817: snes->max_funcs = 10000;
818: snes->norm = 0.0;
819: snes->rtol = 1.e-8;
820: snes->ttol = 0.0;
821: snes->abstol = 1.e-50;
822: snes->xtol = 1.e-8;
823: snes->deltatol = 1.e-12;
824: snes->nfuncs = 0;
825: snes->numFailures = 0;
826: snes->maxFailures = 1;
827: snes->linear_its = 0;
828: snes->numbermonitors = 0;
829: snes->data = 0;
830: snes->setupcalled = PETSC_FALSE;
831: snes->ksp_ewconv = PETSC_FALSE;
832: snes->vwork = 0;
833: snes->nwork = 0;
834: snes->conv_hist_len = 0;
835: snes->conv_hist_max = 0;
836: snes->conv_hist = PETSC_NULL;
837: snes->conv_hist_its = PETSC_NULL;
838: snes->conv_hist_reset = PETSC_TRUE;
839: snes->reason = SNES_CONVERGED_ITERATING;
841: snes->numLinearSolveFailures = 0;
842: snes->maxLinearSolveFailures = 1;
844: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
845: PetscNewLog(snes,SNESKSPEW,&kctx);
846: snes->kspconvctx = (void*)kctx;
847: kctx->version = 2;
848: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
849: this was too large for some test cases */
850: kctx->rtol_last = 0;
851: kctx->rtol_max = .9;
852: kctx->gamma = 1.0;
853: kctx->alpha = .5*(1.0 + sqrt(5.0));
854: kctx->alpha2 = kctx->alpha;
855: kctx->threshold = .1;
856: kctx->lresid_last = 0;
857: kctx->norm_last = 0;
859: KSPCreate(comm,&snes->ksp);
860: PetscLogObjectParent(snes,snes->ksp);
862: *outsnes = snes;
863: PetscPublishAll(snes);
864: return(0);
865: }
869: /*@C
870: SNESSetFunction - Sets the function evaluation routine and function
871: vector for use by the SNES routines in solving systems of nonlinear
872: equations.
874: Collective on SNES
876: Input Parameters:
877: + snes - the SNES context
878: . r - vector to store function value
879: . func - function evaluation routine
880: - ctx - [optional] user-defined context for private data for the
881: function evaluation routine (may be PETSC_NULL)
883: Calling sequence of func:
884: $ func (SNES snes,Vec x,Vec f,void *ctx);
886: . f - function vector
887: - ctx - optional user-defined function context
889: Notes:
890: The Newton-like methods typically solve linear systems of the form
891: $ f'(x) x = -f(x),
892: where f'(x) denotes the Jacobian matrix and f(x) is the function.
894: Level: beginner
896: .keywords: SNES, nonlinear, set, function
898: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
899: @*/
900: PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
901: {
907: PetscObjectReference((PetscObject)r);
908: if (snes->vec_func) { VecDestroy(snes->vec_func); }
909: snes->ops->computefunction = func;
910: snes->vec_func = r;
911: snes->funP = ctx;
912: return(0);
913: }
915: /* --------------------------------------------------------------- */
918: /*@C
919: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
920: it assumes a zero right hand side.
922: Collective on SNES
924: Input Parameter:
925: . snes - the SNES context
927: Output Parameter:
928: . rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null
930: Level: intermediate
932: .keywords: SNES, nonlinear, get, function, right hand side
934: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
935: @*/
936: PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs)
937: {
941: *rhs = snes->vec_rhs;
942: return(0);
943: }
947: /*@
948: SNESComputeFunction - Calls the function that has been set with
949: SNESSetFunction().
951: Collective on SNES
953: Input Parameters:
954: + snes - the SNES context
955: - x - input vector
957: Output Parameter:
958: . y - function vector, as set by SNESSetFunction()
960: Notes:
961: SNESComputeFunction() is typically used within nonlinear solvers
962: implementations, so most users would not generally call this routine
963: themselves.
965: Level: developer
967: .keywords: SNES, nonlinear, compute, function
969: .seealso: SNESSetFunction(), SNESGetFunction()
970: @*/
971: PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y)
972: {
983: if (snes->ops->computefunction) {
984: PetscStackPush("SNES user function");
985: CHKMEMQ;
986: (*snes->ops->computefunction)(snes,x,y,snes->funP);
987: CHKMEMQ;
988: PetscStackPop;
989: if (PetscExceptionValue(ierr)) {
991: }
992:
993: } else if (snes->vec_rhs) {
994: MatMult(snes->jacobian, x, y);
995: } else {
996: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
997: }
998: if (snes->vec_rhs) {
999: VecAXPY(y,-1.0,snes->vec_rhs);
1000: }
1001: snes->nfuncs++;
1003: return(0);
1004: }
1008: /*@
1009: SNESComputeJacobian - Computes the Jacobian matrix that has been
1010: set with SNESSetJacobian().
1012: Collective on SNES and Mat
1014: Input Parameters:
1015: + snes - the SNES context
1016: - x - input vector
1018: Output Parameters:
1019: + A - Jacobian matrix
1020: . B - optional preconditioning matrix
1021: - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
1023: Notes:
1024: Most users should not need to explicitly call this routine, as it
1025: is used internally within the nonlinear solvers.
1027: See KSPSetOperators() for important information about setting the
1028: flag parameter.
1030: Level: developer
1032: .keywords: SNES, compute, Jacobian, matrix
1034: .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure
1035: @*/
1036: PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1037: {
1045: if (!snes->ops->computejacobian) return(0);
1047: *flg = DIFFERENT_NONZERO_PATTERN;
1048: PetscStackPush("SNES user Jacobian function");
1049: CHKMEMQ;
1050: (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1051: CHKMEMQ;
1052: PetscStackPop;
1054: /* make sure user returned a correct Jacobian and preconditioner */
1057: return(0);
1058: }
1062: /*@C
1063: SNESSetJacobian - Sets the function to compute Jacobian as well as the
1064: location to store the matrix.
1066: Collective on SNES and Mat
1068: Input Parameters:
1069: + snes - the SNES context
1070: . A - Jacobian matrix
1071: . B - preconditioner matrix (usually same as the Jacobian)
1072: . func - Jacobian evaluation routine
1073: - ctx - [optional] user-defined context for private data for the
1074: Jacobian evaluation routine (may be PETSC_NULL)
1076: Calling sequence of func:
1077: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
1079: + x - input vector
1080: . A - Jacobian matrix
1081: . B - preconditioner matrix, usually the same as A
1082: . flag - flag indicating information about the preconditioner matrix
1083: structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1084: - ctx - [optional] user-defined Jacobian context
1086: Notes:
1087: See KSPSetOperators() for important information about setting the flag
1088: output parameter in the routine func(). Be sure to read this information!
1090: The routine func() takes Mat * as the matrix arguments rather than Mat.
1091: This allows the Jacobian evaluation routine to replace A and/or B with a
1092: completely new new matrix structure (not just different matrix elements)
1093: when appropriate, for instance, if the nonzero structure is changing
1094: throughout the global iterations.
1096: Level: beginner
1098: .keywords: SNES, nonlinear, set, Jacobian, matrix
1100: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1101: @*/
1102: PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1103: {
1112: if (func) snes->ops->computejacobian = func;
1113: if (ctx) snes->jacP = ctx;
1114: if (A) {
1115: PetscObjectReference((PetscObject)A);
1116: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1117: snes->jacobian = A;
1118: }
1119: if (B) {
1120: PetscObjectReference((PetscObject)B);
1121: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1122: snes->jacobian_pre = B;
1123: }
1124: return(0);
1125: }
1129: /*@C
1130: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1131: provided context for evaluating the Jacobian.
1133: Not Collective, but Mat object will be parallel if SNES object is
1135: Input Parameter:
1136: . snes - the nonlinear solver context
1138: Output Parameters:
1139: + A - location to stash Jacobian matrix (or PETSC_NULL)
1140: . B - location to stash preconditioner matrix (or PETSC_NULL)
1141: . func - location to put Jacobian function (or PETSC_NULL)
1142: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
1144: Level: advanced
1146: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1147: @*/
1148: PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1149: {
1152: if (A) *A = snes->jacobian;
1153: if (B) *B = snes->jacobian_pre;
1154: if (func) *func = snes->ops->computejacobian;
1155: if (ctx) *ctx = snes->jacP;
1156: return(0);
1157: }
1159: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1160: EXTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
1164: /*@
1165: SNESSetUp - Sets up the internal data structures for the later use
1166: of a nonlinear solver.
1168: Collective on SNES
1170: Input Parameters:
1171: . snes - the SNES context
1173: Notes:
1174: For basic use of the SNES solvers the user need not explicitly call
1175: SNESSetUp(), since these actions will automatically occur during
1176: the call to SNESSolve(). However, if one wishes to control this
1177: phase separately, SNESSetUp() should be called after SNESCreate()
1178: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1180: Level: advanced
1182: .keywords: SNES, nonlinear, setup
1184: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1185: @*/
1186: PetscErrorCode SNESSetUp(SNES snes)
1187: {
1189: PetscTruth flg;
1193: if (snes->setupcalled) return(0);
1195: if (!((PetscObject)snes)->type_name) {
1196: SNESSetType(snes,SNESLS);
1197: }
1199: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator",&flg);
1200: /*
1201: This version replaces the user provided Jacobian matrix with a
1202: matrix-free version but still employs the user-provided preconditioner matrix
1203: */
1204: if (flg) {
1205: Mat J;
1206: MatCreateSNESMF(snes,&J);
1207: MatMFFDSetFromOptions(J);
1208: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1209: SNESSetJacobian(snes,J,0,0,0);
1210: MatDestroy(J);
1211: }
1213: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1214: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator2",&flg);
1215: if (flg) {
1216: Mat J;
1217: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1218: PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");
1219: SNESSetJacobian(snes,J,0,0,0);
1220: MatDestroy(J);
1221: }
1222: #endif
1224: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf",&flg);
1225: /*
1226: This version replaces both the user-provided Jacobian and the user-
1227: provided preconditioner matrix with the default matrix free version.
1228: */
1229: if (flg) {
1230: Mat J;
1231: KSP ksp;
1232: PC pc;
1233: /* create and set matrix-free operator */
1234: MatCreateSNESMF(snes,&J);
1235: MatMFFDSetFromOptions(J);
1236: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1237: SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1238: MatDestroy(J);
1239: /* force no preconditioner */
1240: SNESGetKSP(snes,&ksp);
1241: KSPGetPC(ksp,&pc);
1242: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1243: if (!flg) {
1244: PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");
1245: PCSetType(pc,PCNONE);
1246: }
1247: }
1249: if (!snes->vec_func && !snes->vec_rhs) {
1250: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1251: }
1252: if (!snes->ops->computefunction && !snes->vec_rhs) {
1253: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1254: }
1255: if (!snes->jacobian) {
1256: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1257: }
1258: if (snes->vec_func == snes->vec_sol) {
1259: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1260: }
1261:
1262: if (snes->ops->setup) {
1263: (*snes->ops->setup)(snes);
1264: }
1265: snes->setupcalled = PETSC_TRUE;
1266: return(0);
1267: }
1271: /*@
1272: SNESDestroy - Destroys the nonlinear solver context that was created
1273: with SNESCreate().
1275: Collective on SNES
1277: Input Parameter:
1278: . snes - the SNES context
1280: Level: beginner
1282: .keywords: SNES, nonlinear, destroy
1284: .seealso: SNESCreate(), SNESSolve()
1285: @*/
1286: PetscErrorCode SNESDestroy(SNES snes)
1287: {
1292: if (--((PetscObject)snes)->refct > 0) return(0);
1294: /* if memory was published with AMS then destroy it */
1295: PetscObjectDepublish(snes);
1296: if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1297:
1298: if (snes->vec_rhs) {VecDestroy(snes->vec_rhs);}
1299: if (snes->vec_sol) {VecDestroy(snes->vec_sol);}
1300: if (snes->vec_func) {VecDestroy(snes->vec_func);}
1301: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1302: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1303: KSPDestroy(snes->ksp);
1304: PetscFree(snes->kspconvctx);
1305: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1306: SNESMonitorCancel(snes);
1307: PetscHeaderDestroy(snes);
1308: return(0);
1309: }
1311: /* ----------- Routines to set solver parameters ---------- */
1315: /*@
1316: SNESSetTolerances - Sets various parameters used in convergence tests.
1318: Collective on SNES
1320: Input Parameters:
1321: + snes - the SNES context
1322: . abstol - absolute convergence tolerance
1323: . rtol - relative convergence tolerance
1324: . stol - convergence tolerance in terms of the norm
1325: of the change in the solution between steps
1326: . maxit - maximum number of iterations
1327: - maxf - maximum number of function evaluations
1329: Options Database Keys:
1330: + -snes_atol <abstol> - Sets abstol
1331: . -snes_rtol <rtol> - Sets rtol
1332: . -snes_stol <stol> - Sets stol
1333: . -snes_max_it <maxit> - Sets maxit
1334: - -snes_max_funcs <maxf> - Sets maxf
1336: Notes:
1337: The default maximum number of iterations is 50.
1338: The default maximum number of function evaluations is 1000.
1340: Level: intermediate
1342: .keywords: SNES, nonlinear, set, convergence, tolerances
1344: .seealso: SNESSetTrustRegionTolerance()
1345: @*/
1346: PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1347: {
1350: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1351: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1352: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1353: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1354: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1355: return(0);
1356: }
1360: /*@
1361: SNESGetTolerances - Gets various parameters used in convergence tests.
1363: Not Collective
1365: Input Parameters:
1366: + snes - the SNES context
1367: . atol - absolute convergence tolerance
1368: . rtol - relative convergence tolerance
1369: . stol - convergence tolerance in terms of the norm
1370: of the change in the solution between steps
1371: . maxit - maximum number of iterations
1372: - maxf - maximum number of function evaluations
1374: Notes:
1375: The user can specify PETSC_NULL for any parameter that is not needed.
1377: Level: intermediate
1379: .keywords: SNES, nonlinear, get, convergence, tolerances
1381: .seealso: SNESSetTolerances()
1382: @*/
1383: PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1384: {
1387: if (atol) *atol = snes->abstol;
1388: if (rtol) *rtol = snes->rtol;
1389: if (stol) *stol = snes->xtol;
1390: if (maxit) *maxit = snes->max_its;
1391: if (maxf) *maxf = snes->max_funcs;
1392: return(0);
1393: }
1397: /*@
1398: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1400: Collective on SNES
1402: Input Parameters:
1403: + snes - the SNES context
1404: - tol - tolerance
1405:
1406: Options Database Key:
1407: . -snes_trtol <tol> - Sets tol
1409: Level: intermediate
1411: .keywords: SNES, nonlinear, set, trust region, tolerance
1413: .seealso: SNESSetTolerances()
1414: @*/
1415: PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1416: {
1419: snes->deltatol = tol;
1420: return(0);
1421: }
1423: /*
1424: Duplicate the lg monitors for SNES from KSP; for some reason with
1425: dynamic libraries things don't work under Sun4 if we just use
1426: macros instead of functions
1427: */
1430: PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1431: {
1436: KSPMonitorLG((KSP)snes,it,norm,ctx);
1437: return(0);
1438: }
1442: PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1443: {
1447: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1448: return(0);
1449: }
1453: PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG draw)
1454: {
1458: KSPMonitorLGDestroy(draw);
1459: return(0);
1460: }
1462: /* ------------ Routines to set performance monitoring options ----------- */
1466: /*@C
1467: SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1468: iteration of the nonlinear solver to display the iteration's
1469: progress.
1471: Collective on SNES
1473: Input Parameters:
1474: + snes - the SNES context
1475: . func - monitoring routine
1476: . mctx - [optional] user-defined context for private data for the
1477: monitor routine (use PETSC_NULL if no context is desired)
1478: - monitordestroy - [optional] routine that frees monitor context
1479: (may be PETSC_NULL)
1481: Calling sequence of func:
1482: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1484: + snes - the SNES context
1485: . its - iteration number
1486: . norm - 2-norm function value (may be estimated)
1487: - mctx - [optional] monitoring context
1489: Options Database Keys:
1490: + -snes_monitor - sets SNESMonitorDefault()
1491: . -snes_monitor_draw - sets line graph monitor,
1492: uses SNESMonitorLGCreate()
1493: _ -snes_monitor_cancel - cancels all monitors that have
1494: been hardwired into a code by
1495: calls to SNESMonitorSet(), but
1496: does not cancel those set via
1497: the options database.
1499: Notes:
1500: Several different monitoring routines may be set by calling
1501: SNESMonitorSet() multiple times; all will be called in the
1502: order in which they were set.
1504: Level: intermediate
1506: .keywords: SNES, nonlinear, set, monitor
1508: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1509: @*/
1510: PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1511: {
1512: PetscInt i;
1516: if (snes->numbermonitors >= MAXSNESMONITORS) {
1517: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1518: }
1519: for (i=0; i<snes->numbermonitors;i++) {
1520: if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);
1522: /* check if both default monitors that share common ASCII viewer */
1523: if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1524: if (mctx && snes->monitorcontext[i]) {
1525: PetscErrorCode ierr;
1526: PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1527: PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1528: if (viewer1->viewer == viewer2->viewer) {
1529: (*monitordestroy)(mctx);
1530: return(0);
1531: }
1532: }
1533: }
1534: }
1535: snes->monitor[snes->numbermonitors] = monitor;
1536: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1537: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1538: return(0);
1539: }
1543: /*@C
1544: SNESMonitorCancel - Clears all the monitor functions for a SNES object.
1546: Collective on SNES
1548: Input Parameters:
1549: . snes - the SNES context
1551: Options Database Key:
1552: . -snes_monitor_cancel - cancels all monitors that have been hardwired
1553: into a code by calls to SNESMonitorSet(), but does not cancel those
1554: set via the options database
1556: Notes:
1557: There is no way to clear one specific monitor from a SNES object.
1559: Level: intermediate
1561: .keywords: SNES, nonlinear, set, monitor
1563: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1564: @*/
1565: PetscErrorCode SNESMonitorCancel(SNES snes)
1566: {
1568: PetscInt i;
1572: for (i=0; i<snes->numbermonitors; i++) {
1573: if (snes->monitordestroy[i]) {
1574: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1575: }
1576: }
1577: snes->numbermonitors = 0;
1578: return(0);
1579: }
1583: /*@C
1584: SNESSetConvergenceTest - Sets the function that is to be used
1585: to test for convergence of the nonlinear iterative solution.
1587: Collective on SNES
1589: Input Parameters:
1590: + snes - the SNES context
1591: . func - routine to test for convergence
1592: - cctx - [optional] context for private data for the convergence routine
1593: (may be PETSC_NULL)
1595: Calling sequence of func:
1596: $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1598: + snes - the SNES context
1599: . it - current iteration (0 is the first and is before any Newton step)
1600: . cctx - [optional] convergence context
1601: . reason - reason for convergence/divergence
1602: . xnorm - 2-norm of current iterate
1603: . gnorm - 2-norm of current step
1604: - f - 2-norm of function
1606: Level: advanced
1608: .keywords: SNES, nonlinear, set, convergence, test
1610: .seealso: SNESDefaultConverged(), SNESSkipConverged()
1611: @*/
1612: PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1613: {
1616: if (!func) func = SNESSkipConverged;
1617: snes->ops->converged = func;
1618: snes->cnvP = cctx;
1619: return(0);
1620: }
1624: /*@
1625: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1627: Not Collective
1629: Input Parameter:
1630: . snes - the SNES context
1632: Output Parameter:
1633: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1634: manual pages for the individual convergence tests for complete lists
1636: Level: intermediate
1638: Notes: Can only be called after the call the SNESSolve() is complete.
1640: .keywords: SNES, nonlinear, set, convergence, test
1642: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1643: @*/
1644: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1645: {
1649: *reason = snes->reason;
1650: return(0);
1651: }
1655: /*@
1656: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1658: Collective on SNES
1660: Input Parameters:
1661: + snes - iterative context obtained from SNESCreate()
1662: . a - array to hold history
1663: . its - integer array holds the number of linear iterations for each solve.
1664: . na - size of a and its
1665: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1666: else it continues storing new values for new nonlinear solves after the old ones
1668: Notes:
1669: If set, this array will contain the function norms computed
1670: at each step.
1672: This routine is useful, e.g., when running a code for purposes
1673: of accurate performance monitoring, when no I/O should be done
1674: during the section of code that is being timed.
1676: Level: intermediate
1678: .keywords: SNES, set, convergence, history
1680: .seealso: SNESGetConvergenceHistory()
1682: @*/
1683: PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
1684: {
1689: snes->conv_hist = a;
1690: snes->conv_hist_its = its;
1691: snes->conv_hist_max = na;
1692: snes->conv_hist_reset = reset;
1693: return(0);
1694: }
1698: /*@C
1699: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1701: Collective on SNES
1703: Input Parameter:
1704: . snes - iterative context obtained from SNESCreate()
1706: Output Parameters:
1707: . a - array to hold history
1708: . its - integer array holds the number of linear iterations (or
1709: negative if not converged) for each solve.
1710: - na - size of a and its
1712: Notes:
1713: The calling sequence for this routine in Fortran is
1714: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1716: This routine is useful, e.g., when running a code for purposes
1717: of accurate performance monitoring, when no I/O should be done
1718: during the section of code that is being timed.
1720: Level: intermediate
1722: .keywords: SNES, get, convergence, history
1724: .seealso: SNESSetConvergencHistory()
1726: @*/
1727: PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1728: {
1731: if (a) *a = snes->conv_hist;
1732: if (its) *its = snes->conv_hist_its;
1733: if (na) *na = snes->conv_hist_len;
1734: return(0);
1735: }
1739: /*@C
1740: SNESSetUpdate - Sets the general-purpose update function called
1741: at the beginning o every iteration of the nonlinear solve. Specifically
1742: it is called just before the Jacobian is "evaluated".
1744: Collective on SNES
1746: Input Parameters:
1747: . snes - The nonlinear solver context
1748: . func - The function
1750: Calling sequence of func:
1751: . func (SNES snes, PetscInt step);
1753: . step - The current step of the iteration
1755: Level: intermediate
1757: .keywords: SNES, update
1759: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
1760: @*/
1761: PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1762: {
1765: snes->ops->update = func;
1766: return(0);
1767: }
1771: /*@
1772: SNESDefaultUpdate - The default update function which does nothing.
1774: Not collective
1776: Input Parameters:
1777: . snes - The nonlinear solver context
1778: . step - The current step of the iteration
1780: Level: intermediate
1782: .keywords: SNES, update
1783: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
1784: @*/
1785: PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step)
1786: {
1788: return(0);
1789: }
1793: /*
1794: SNESScaleStep_Private - Scales a step so that its length is less than the
1795: positive parameter delta.
1797: Input Parameters:
1798: + snes - the SNES context
1799: . y - approximate solution of linear system
1800: . fnorm - 2-norm of current function
1801: - delta - trust region size
1803: Output Parameters:
1804: + gpnorm - predicted function norm at the new point, assuming local
1805: linearization. The value is zero if the step lies within the trust
1806: region, and exceeds zero otherwise.
1807: - ynorm - 2-norm of the step
1809: Note:
1810: For non-trust region methods such as SNESLS, the parameter delta
1811: is set to be the maximum allowable step size.
1813: .keywords: SNES, nonlinear, scale, step
1814: */
1815: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1816: {
1817: PetscReal nrm;
1818: PetscScalar cnorm;
1826: VecNorm(y,NORM_2,&nrm);
1827: if (nrm > *delta) {
1828: nrm = *delta/nrm;
1829: *gpnorm = (1.0 - nrm)*(*fnorm);
1830: cnorm = nrm;
1831: VecScale(y,cnorm);
1832: *ynorm = *delta;
1833: } else {
1834: *gpnorm = 0.0;
1835: *ynorm = nrm;
1836: }
1837: return(0);
1838: }
1842: /*@C
1843: SNESSolve - Solves a nonlinear system F(x) = b.
1844: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
1846: Collective on SNES
1848: Input Parameters:
1849: + snes - the SNES context
1850: . b - the constant part of the equation, or PETSC_NULL to use zero.
1851: - x - the solution vector.
1853: Notes:
1854: The user should initialize the vector,x, with the initial guess
1855: for the nonlinear solve prior to calling SNESSolve. In particular,
1856: to employ an initial guess of zero, the user should explicitly set
1857: this vector to zero by calling VecSet().
1859: Level: beginner
1861: .keywords: SNES, nonlinear, solve
1863: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
1864: @*/
1865: PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x)
1866: {
1868: PetscTruth flg;
1869: char filename[PETSC_MAX_PATH_LEN];
1870: PetscViewer viewer;
1879: /* set solution vector */
1880: PetscObjectReference((PetscObject)x);
1881: if (snes->vec_sol) { VecDestroy(snes->vec_sol); }
1882: snes->vec_sol = x;
1883: /* set afine vector if provided */
1884: if (b) { PetscObjectReference((PetscObject)b); }
1885: if (snes->vec_rhs) { VecDestroy(snes->vec_rhs); }
1886: snes->vec_rhs = b;
1887:
1888: if (!snes->vec_func && snes->vec_rhs) {
1889: VecDuplicate(b, &snes->vec_func);
1890: }
1892: SNESSetUp(snes);
1894: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1895: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1898: (*snes->ops->solve)(snes);
1900: if (snes->domainerror){
1901: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
1902: snes->domainerror = PETSC_FALSE;
1903: }
1905: if (!snes->reason) {
1906: SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
1907: }
1908:
1909: PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
1910: if (flg && !PetscPreLoadingOn) {
1911: PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
1912: SNESView(snes,viewer);
1913: PetscViewerDestroy(viewer);
1914: }
1916: PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);
1917: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1918: if (snes->printreason) {
1919: if (snes->reason > 0) {
1920: PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1921: } else {
1922: PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1923: }
1924: }
1926: return(0);
1927: }
1929: /* --------- Internal routines for SNES Package --------- */
1933: /*@C
1934: SNESSetType - Sets the method for the nonlinear solver.
1936: Collective on SNES
1938: Input Parameters:
1939: + snes - the SNES context
1940: - type - a known method
1942: Options Database Key:
1943: . -snes_type <type> - Sets the method; use -help for a list
1944: of available methods (for instance, ls or tr)
1946: Notes:
1947: See "petsc/include/petscsnes.h" for available methods (for instance)
1948: + SNESLS - Newton's method with line search
1949: (systems of nonlinear equations)
1950: . SNESTR - Newton's method with trust region
1951: (systems of nonlinear equations)
1953: Normally, it is best to use the SNESSetFromOptions() command and then
1954: set the SNES solver type from the options database rather than by using
1955: this routine. Using the options database provides the user with
1956: maximum flexibility in evaluating the many nonlinear solvers.
1957: The SNESSetType() routine is provided for those situations where it
1958: is necessary to set the nonlinear solver independently of the command
1959: line or options database. This might be the case, for example, when
1960: the choice of solver changes during the execution of the program,
1961: and the user's application is taking responsibility for choosing the
1962: appropriate method.
1964: Level: intermediate
1966: .keywords: SNES, set, type
1968: .seealso: SNESType, SNESCreate()
1970: @*/
1971: PetscErrorCode SNESSetType(SNES snes,SNESType type)
1972: {
1973: PetscErrorCode ierr,(*r)(SNES);
1974: PetscTruth match;
1980: PetscTypeCompare((PetscObject)snes,type,&match);
1981: if (match) return(0);
1983: PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);
1984: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1985: /* Destroy the previous private SNES context */
1986: if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
1987: /* Reinitialize function pointers in SNESOps structure */
1988: snes->ops->setup = 0;
1989: snes->ops->solve = 0;
1990: snes->ops->view = 0;
1991: snes->ops->setfromoptions = 0;
1992: snes->ops->destroy = 0;
1993: /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
1994: snes->setupcalled = PETSC_FALSE;
1995: (*r)(snes);
1996: PetscObjectChangeTypeName((PetscObject)snes,type);
1997: return(0);
1998: }
2001: /* --------------------------------------------------------------------- */
2004: /*@
2005: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2006: registered by SNESRegisterDynamic().
2008: Not Collective
2010: Level: advanced
2012: .keywords: SNES, nonlinear, register, destroy
2014: .seealso: SNESRegisterAll(), SNESRegisterAll()
2015: @*/
2016: PetscErrorCode SNESRegisterDestroy(void)
2017: {
2021: PetscFListDestroy(&SNESList);
2022: SNESRegisterAllCalled = PETSC_FALSE;
2023: return(0);
2024: }
2028: /*@C
2029: SNESGetType - Gets the SNES method type and name (as a string).
2031: Not Collective
2033: Input Parameter:
2034: . snes - nonlinear solver context
2036: Output Parameter:
2037: . type - SNES method (a character string)
2039: Level: intermediate
2041: .keywords: SNES, nonlinear, get, type, name
2042: @*/
2043: PetscErrorCode SNESGetType(SNES snes,SNESType *type)
2044: {
2048: *type = ((PetscObject)snes)->type_name;
2049: return(0);
2050: }
2054: /*@
2055: SNESGetSolution - Returns the vector where the approximate solution is
2056: stored.
2058: Not Collective, but Vec is parallel if SNES is parallel
2060: Input Parameter:
2061: . snes - the SNES context
2063: Output Parameter:
2064: . x - the solution
2066: Level: intermediate
2068: .keywords: SNES, nonlinear, get, solution
2070: .seealso: SNESGetSolutionUpdate(), SNESGetFunction()
2071: @*/
2072: PetscErrorCode SNESGetSolution(SNES snes,Vec *x)
2073: {
2077: *x = snes->vec_sol;
2078: return(0);
2079: }
2083: /*@
2084: SNESGetSolutionUpdate - Returns the vector where the solution update is
2085: stored.
2087: Not Collective, but Vec is parallel if SNES is parallel
2089: Input Parameter:
2090: . snes - the SNES context
2092: Output Parameter:
2093: . x - the solution update
2095: Level: advanced
2097: .keywords: SNES, nonlinear, get, solution, update
2099: .seealso: SNESGetSolution(), SNESGetFunction()
2100: @*/
2101: PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x)
2102: {
2106: *x = snes->vec_sol_update;
2107: return(0);
2108: }
2112: /*@C
2113: SNESGetFunction - Returns the vector where the function is stored.
2115: Not Collective, but Vec is parallel if SNES is parallel
2117: Input Parameter:
2118: . snes - the SNES context
2120: Output Parameter:
2121: + r - the function (or PETSC_NULL)
2122: . func - the function (or PETSC_NULL)
2123: - ctx - the function context (or PETSC_NULL)
2125: Level: advanced
2127: .keywords: SNES, nonlinear, get, function
2129: .seealso: SNESSetFunction(), SNESGetSolution()
2130: @*/
2131: PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2132: {
2135: if (r) *r = snes->vec_func;
2136: if (func) *func = snes->ops->computefunction;
2137: if (ctx) *ctx = snes->funP;
2138: return(0);
2139: }
2143: /*@C
2144: SNESSetOptionsPrefix - Sets the prefix used for searching for all
2145: SNES options in the database.
2147: Collective on SNES
2149: Input Parameter:
2150: + snes - the SNES context
2151: - prefix - the prefix to prepend to all option names
2153: Notes:
2154: A hyphen (-) must NOT be given at the beginning of the prefix name.
2155: The first character of all runtime options is AUTOMATICALLY the hyphen.
2157: Level: advanced
2159: .keywords: SNES, set, options, prefix, database
2161: .seealso: SNESSetFromOptions()
2162: @*/
2163: PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[])
2164: {
2169: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2170: KSPSetOptionsPrefix(snes->ksp,prefix);
2171: return(0);
2172: }
2176: /*@C
2177: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2178: SNES options in the database.
2180: Collective on SNES
2182: Input Parameters:
2183: + snes - the SNES context
2184: - prefix - the prefix to prepend to all option names
2186: Notes:
2187: A hyphen (-) must NOT be given at the beginning of the prefix name.
2188: The first character of all runtime options is AUTOMATICALLY the hyphen.
2190: Level: advanced
2192: .keywords: SNES, append, options, prefix, database
2194: .seealso: SNESGetOptionsPrefix()
2195: @*/
2196: PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2197: {
2199:
2202: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2203: KSPAppendOptionsPrefix(snes->ksp,prefix);
2204: return(0);
2205: }
2209: /*@C
2210: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2211: SNES options in the database.
2213: Not Collective
2215: Input Parameter:
2216: . snes - the SNES context
2218: Output Parameter:
2219: . prefix - pointer to the prefix string used
2221: Notes: On the fortran side, the user should pass in a string 'prifix' of
2222: sufficient length to hold the prefix.
2224: Level: advanced
2226: .keywords: SNES, get, options, prefix, database
2228: .seealso: SNESAppendOptionsPrefix()
2229: @*/
2230: PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2231: {
2236: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2237: return(0);
2238: }
2243: /*@C
2244: SNESRegister - See SNESRegisterDynamic()
2246: Level: advanced
2247: @*/
2248: PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2249: {
2250: char fullname[PETSC_MAX_PATH_LEN];
2254: PetscFListConcat(path,name,fullname);
2255: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2256: return(0);
2257: }
2261: PetscErrorCode SNESTestLocalMin(SNES snes)
2262: {
2264: PetscInt N,i,j;
2265: Vec u,uh,fh;
2266: PetscScalar value;
2267: PetscReal norm;
2270: SNESGetSolution(snes,&u);
2271: VecDuplicate(u,&uh);
2272: VecDuplicate(u,&fh);
2274: /* currently only works for sequential */
2275: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2276: VecGetSize(u,&N);
2277: for (i=0; i<N; i++) {
2278: VecCopy(u,uh);
2279: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2280: for (j=-10; j<11; j++) {
2281: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2282: VecSetValue(uh,i,value,ADD_VALUES);
2283: SNESComputeFunction(snes,uh,fh);
2284: VecNorm(fh,NORM_2,&norm);
2285: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2286: value = -value;
2287: VecSetValue(uh,i,value,ADD_VALUES);
2288: }
2289: }
2290: VecDestroy(uh);
2291: VecDestroy(fh);
2292: return(0);
2293: }
2297: /*@
2298: SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2299: computing relative tolerance for linear solvers within an inexact
2300: Newton method.
2302: Collective on SNES
2304: Input Parameters:
2305: + snes - SNES context
2306: - flag - PETSC_TRUE or PETSC_FALSE
2308: Notes:
2309: Currently, the default is to use a constant relative tolerance for
2310: the inner linear solvers. Alternatively, one can use the
2311: Eisenstat-Walker method, where the relative convergence tolerance
2312: is reset at each Newton iteration according progress of the nonlinear
2313: solver.
2315: Level: advanced
2317: Reference:
2318: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2319: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2321: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2323: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2324: @*/
2325: PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2326: {
2329: snes->ksp_ewconv = flag;
2330: return(0);
2331: }
2335: /*@
2336: SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2337: for computing relative tolerance for linear solvers within an
2338: inexact Newton method.
2340: Not Collective
2342: Input Parameter:
2343: . snes - SNES context
2345: Output Parameter:
2346: . flag - PETSC_TRUE or PETSC_FALSE
2348: Notes:
2349: Currently, the default is to use a constant relative tolerance for
2350: the inner linear solvers. Alternatively, one can use the
2351: Eisenstat-Walker method, where the relative convergence tolerance
2352: is reset at each Newton iteration according progress of the nonlinear
2353: solver.
2355: Level: advanced
2357: Reference:
2358: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2359: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2361: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2363: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2364: @*/
2365: PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2366: {
2370: *flag = snes->ksp_ewconv;
2371: return(0);
2372: }
2376: /*@
2377: SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2378: convergence criteria for the linear solvers within an inexact
2379: Newton method.
2381: Collective on SNES
2382:
2383: Input Parameters:
2384: + snes - SNES context
2385: . version - version 1, 2 (default is 2) or 3
2386: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2387: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2388: . gamma - multiplicative factor for version 2 rtol computation
2389: (0 <= gamma2 <= 1)
2390: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2391: . alpha2 - power for safeguard
2392: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2394: Note:
2395: Version 3 was contributed by Luis Chacon, June 2006.
2397: Use PETSC_DEFAULT to retain the default for any of the parameters.
2399: Level: advanced
2401: Reference:
2402: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2403: inexact Newton method", Utah State University Math. Stat. Dept. Res.
2404: Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
2406: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
2408: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2409: @*/
2410: PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2411: PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2412: {
2413: SNESKSPEW *kctx;
2416: kctx = (SNESKSPEW*)snes->kspconvctx;
2417: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2419: if (version != PETSC_DEFAULT) kctx->version = version;
2420: if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
2421: if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max;
2422: if (gamma != PETSC_DEFAULT) kctx->gamma = gamma;
2423: if (alpha != PETSC_DEFAULT) kctx->alpha = alpha;
2424: if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2;
2425: if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2426:
2427: if (kctx->version < 1 || kctx->version > 3) {
2428: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2429: }
2430: if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2431: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2432: }
2433: if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2434: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2435: }
2436: if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2437: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2438: }
2439: if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2440: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2441: }
2442: if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2443: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2444: }
2445: return(0);
2446: }
2450: /*@
2451: SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2452: convergence criteria for the linear solvers within an inexact
2453: Newton method.
2455: Not Collective
2456:
2457: Input Parameters:
2458: snes - SNES context
2460: Output Parameters:
2461: + version - version 1, 2 (default is 2) or 3
2462: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2463: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2464: . gamma - multiplicative factor for version 2 rtol computation
2465: (0 <= gamma2 <= 1)
2466: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2467: . alpha2 - power for safeguard
2468: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2470: Level: advanced
2472: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
2474: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2475: @*/
2476: PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2477: PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2478: {
2479: SNESKSPEW *kctx;
2482: kctx = (SNESKSPEW*)snes->kspconvctx;
2483: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2484: if(version) *version = kctx->version;
2485: if(rtol_0) *rtol_0 = kctx->rtol_0;
2486: if(rtol_max) *rtol_max = kctx->rtol_max;
2487: if(gamma) *gamma = kctx->gamma;
2488: if(alpha) *alpha = kctx->alpha;
2489: if(alpha2) *alpha2 = kctx->alpha2;
2490: if(threshold) *threshold = kctx->threshold;
2491: return(0);
2492: }
2496: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2497: {
2499: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2500: PetscReal rtol=PETSC_DEFAULT,stol;
2503: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2504: if (!snes->iter) { /* first time in, so use the original user rtol */
2505: rtol = kctx->rtol_0;
2506: } else {
2507: if (kctx->version == 1) {
2508: rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2509: if (rtol < 0.0) rtol = -rtol;
2510: stol = pow(kctx->rtol_last,kctx->alpha2);
2511: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2512: } else if (kctx->version == 2) {
2513: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2514: stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2515: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2516: } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2517: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2518: /* safeguard: avoid sharp decrease of rtol */
2519: stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2520: stol = PetscMax(rtol,stol);
2521: rtol = PetscMin(kctx->rtol_0,stol);
2522: /* safeguard: avoid oversolving */
2523: stol = kctx->gamma*(snes->ttol)/snes->norm;
2524: stol = PetscMax(rtol,stol);
2525: rtol = PetscMin(kctx->rtol_0,stol);
2526: } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2527: }
2528: /* safeguard: avoid rtol greater than one */
2529: rtol = PetscMin(rtol,kctx->rtol_max);
2530: KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2531: PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2532: return(0);
2533: }
2537: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2538: {
2540: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2541: PCSide pcside;
2542: Vec lres;
2545: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2546: KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2547: SNESGetFunctionNorm(snes,&kctx->norm_last);
2548: if (kctx->version == 1) {
2549: KSPGetPreconditionerSide(ksp,&pcside);
2550: if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2551: /* KSP residual is true linear residual */
2552: KSPGetResidualNorm(ksp,&kctx->lresid_last);
2553: } else {
2554: /* KSP residual is preconditioned residual */
2555: /* compute true linear residual norm */
2556: VecDuplicate(b,&lres);
2557: MatMult(snes->jacobian,x,lres);
2558: VecAYPX(lres,-1.0,b);
2559: VecNorm(lres,NORM_2,&kctx->lresid_last);
2560: VecDestroy(lres);
2561: }
2562: }
2563: return(0);
2564: }
2568: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2569: {
2573: if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x); }
2574: KSPSolve(ksp,b,x);
2575: if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2576: return(0);
2577: }