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: SNESView - Prints the SNES data structure.
17: Collective on SNES
19: Input Parameters:
20: + SNES - the SNES context
21: - viewer - visualization context
23: Options Database Key:
24: . -snes_view - Calls SNESView() at end of SNESSolve()
26: Notes:
27: The available visualization contexts include
28: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
29: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
30: output where only the first processor opens
31: the file. All other processors send their
32: data to the first processor to print.
34: The user can open an alternative visualization context with
35: PetscViewerASCIIOpen() - output to a specified file.
37: Level: beginner
39: .keywords: SNES, view
41: .seealso: PetscViewerASCIIOpen()
42: @*/
43: PetscErrorCode SNESView(SNES snes,PetscViewer viewer)
44: {
45: SNESKSPEW *kctx;
46: PetscErrorCode ierr;
47: KSP ksp;
48: SNESType type;
49: PetscTruth iascii,isstring;
53: if (!viewer) {
54: PetscViewerASCIIGetStdout(snes->comm,&viewer);
55: }
59: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
60: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
61: if (iascii) {
62: if (snes->prefix) {
63: PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",snes->prefix);
64: } else {
65: PetscViewerASCIIPrintf(viewer,"SNES Object:\n");
66: }
67: SNESGetType(snes,&type);
68: if (type) {
69: PetscViewerASCIIPrintf(viewer," type: %s\n",type);
70: } else {
71: PetscViewerASCIIPrintf(viewer," type: not set yet\n");
72: }
73: if (snes->ops->view) {
74: PetscViewerASCIIPushTab(viewer);
75: (*snes->ops->view)(snes,viewer);
76: PetscViewerASCIIPopTab(viewer);
77: }
78: PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
79: PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n",
80: snes->rtol,snes->abstol,snes->xtol);
81: PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);
82: PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);
83: if (snes->ksp_ewconv) {
84: kctx = (SNESKSPEW *)snes->kspconvctx;
85: if (kctx) {
86: PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
87: PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
88: PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
89: }
90: }
91: } else if (isstring) {
92: SNESGetType(snes,&type);
93: PetscViewerStringSPrintf(viewer," %-3.3s",type);
94: }
95: SNESGetKSP(snes,&ksp);
96: PetscViewerASCIIPushTab(viewer);
97: KSPView(ksp,viewer);
98: PetscViewerASCIIPopTab(viewer);
99: return(0);
100: }
102: /*
103: We retain a list of functions that also take SNES command
104: line options. These are called at the end SNESSetFromOptions()
105: */
106: #define MAXSETFROMOPTIONS 5
107: static PetscInt numberofsetfromoptions;
108: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
112: /*@C
113: SNESAddOptionsChecker - Adds an additional function to check for SNES options.
115: Not Collective
117: Input Parameter:
118: . snescheck - function that checks for options
120: Level: developer
122: .seealso: SNESSetFromOptions()
123: @*/
124: PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
125: {
127: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
128: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
129: }
130: othersetfromoptions[numberofsetfromoptions++] = snescheck;
131: return(0);
132: }
136: /*@
137: SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
139: Collective on SNES
141: Input Parameter:
142: . snes - the SNES context
144: Options Database Keys:
145: + -snes_type <type> - ls, tr, umls, umtr, test
146: . -snes_stol - convergence tolerance in terms of the norm
147: of the change in the solution between steps
148: . -snes_atol <abstol> - absolute tolerance of residual norm
149: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
150: . -snes_max_it <max_it> - maximum number of iterations
151: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
152: . -snes_max_fail <max_fail> - maximum number of failures
153: . -snes_trtol <trtol> - trust region tolerance
154: . -snes_no_convergence_test - skip convergence test in nonlinear
155: solver; hence iterations will continue until max_it
156: or some other criterion is reached. Saves expense
157: of convergence test
158: . -snes_monitor <optional filename> - prints residual norm at each iteration. if no
159: filename given prints to stdout
160: . -snes_monitor_solution - plots solution at each iteration
161: . -snes_monitor_residual - plots residual (not its norm) at each iteration
162: . -snes_monitor_solution_update - plots update to solution at each iteration
163: . -snes_monitor_draw - plots residual norm at each iteration
164: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
165: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
166: - -snes_converged_reason - print the reason for convergence/divergence after each solve
168: Options Database for Eisenstat-Walker method:
169: + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
170: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
171: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
172: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
173: . -snes_ksp_ew_gamma <gamma> - Sets gamma
174: . -snes_ksp_ew_alpha <alpha> - Sets alpha
175: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
176: - -snes_ksp_ew_threshold <threshold> - Sets threshold
178: Notes:
179: To see all options, run your program with the -help option or consult
180: the users manual.
182: Level: beginner
184: .keywords: SNES, nonlinear, set, options, database
186: .seealso: SNESSetOptionsPrefix()
187: @*/
188: PetscErrorCode SNESSetFromOptions(SNES snes)
189: {
190: KSP ksp;
191: SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx;
192: PetscTruth flg;
193: PetscErrorCode ierr;
194: PetscInt i;
195: const char *deft;
196: char type[256], monfilename[PETSC_MAX_PATH_LEN];
197: PetscViewerASCIIMonitor monviewer;
202: PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");
203: if (snes->type_name) {
204: deft = snes->type_name;
205: } else {
206: deft = SNESLS;
207: }
209: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
210: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
211: if (flg) {
212: SNESSetType(snes,type);
213: } else if (!snes->type_name) {
214: SNESSetType(snes,deft);
215: }
216: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
218: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
219: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);
221: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
222: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
223: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
224: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
225: PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
226: if (flg) {
227: snes->printreason = PETSC_TRUE;
228: }
230: PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
232: PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
233: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
234: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
235: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
236: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
237: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
238: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);
240: PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);
241: if (flg) {snes->ops->converged = 0;}
242: PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);
243: if (flg) {SNESMonitorCancel(snes);}
245: PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
246: if (flg) {
247: PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);
248: SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
249: }
251: PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
252: if (flg) {
253: PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);
254: SNESMonitorSetRatio(snes,monviewer);
255: }
257: PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
258: if (flg) {
259: PetscViewerASCIIMonitorCreate(snes->comm,monfilename,0,&monviewer);
260: SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
261: }
263: PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);
264: if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
265: PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);
266: if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
267: PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);
268: if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
269: PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);
270: if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}
272: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
273: if (flg) {
274: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
275: PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
276: }
278: for(i = 0; i < numberofsetfromoptions; i++) {
279: (*othersetfromoptions[i])(snes);
280: }
282: if (snes->ops->setfromoptions) {
283: (*snes->ops->setfromoptions)(snes);
284: }
285: PetscOptionsEnd();
287: SNESGetKSP(snes,&ksp);
288: KSPSetFromOptions(ksp);
290: return(0);
291: }
296: /*@
297: SNESSetApplicationContext - Sets the optional user-defined context for
298: the nonlinear solvers.
300: Collective on SNES
302: Input Parameters:
303: + snes - the SNES context
304: - usrP - optional user context
306: Level: intermediate
308: .keywords: SNES, nonlinear, set, application, context
310: .seealso: SNESGetApplicationContext()
311: @*/
312: PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP)
313: {
316: snes->user = usrP;
317: return(0);
318: }
322: /*@C
323: SNESGetApplicationContext - Gets the user-defined context for the
324: nonlinear solvers.
326: Not Collective
328: Input Parameter:
329: . snes - SNES context
331: Output Parameter:
332: . usrP - user context
334: Level: intermediate
336: .keywords: SNES, nonlinear, get, application, context
338: .seealso: SNESSetApplicationContext()
339: @*/
340: PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP)
341: {
344: *usrP = snes->user;
345: return(0);
346: }
350: /*@
351: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
352: at this time.
354: Not Collective
356: Input Parameter:
357: . snes - SNES context
359: Output Parameter:
360: . iter - iteration number
362: Notes:
363: For example, during the computation of iteration 2 this would return 1.
365: This is useful for using lagged Jacobians (where one does not recompute the
366: Jacobian at each SNES iteration). For example, the code
367: .vb
368: SNESGetIterationNumber(snes,&it);
369: if (!(it % 2)) {
370: [compute Jacobian here]
371: }
372: .ve
373: can be used in your ComputeJacobian() function to cause the Jacobian to be
374: recomputed every second SNES iteration.
376: Level: intermediate
378: .keywords: SNES, nonlinear, get, iteration, number,
380: .seealso: SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
381: @*/
382: PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter)
383: {
387: *iter = snes->iter;
388: return(0);
389: }
393: /*@
394: SNESGetFunctionNorm - Gets the norm of the current function that was set
395: with SNESSSetFunction().
397: Collective on SNES
399: Input Parameter:
400: . snes - SNES context
402: Output Parameter:
403: . fnorm - 2-norm of function
405: Level: intermediate
407: .keywords: SNES, nonlinear, get, function, norm
409: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
410: @*/
411: PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
412: {
416: *fnorm = snes->norm;
417: return(0);
418: }
422: /*@
423: SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
424: attempted by the nonlinear solver.
426: Not Collective
428: Input Parameter:
429: . snes - SNES context
431: Output Parameter:
432: . nfails - number of unsuccessful steps attempted
434: Notes:
435: This counter is reset to zero for each successive call to SNESSolve().
437: Level: intermediate
439: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
440: @*/
441: PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
442: {
446: *nfails = snes->numFailures;
447: return(0);
448: }
452: /*@
453: SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
454: attempted by the nonlinear solver before it gives up.
456: Not Collective
458: Input Parameters:
459: + snes - SNES context
460: - maxFails - maximum of unsuccessful steps
462: Level: intermediate
464: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
465: @*/
466: PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
467: {
470: snes->maxFailures = maxFails;
471: return(0);
472: }
476: /*@
477: SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
478: attempted by the nonlinear solver before it gives up.
480: Not Collective
482: Input Parameter:
483: . snes - SNES context
485: Output Parameter:
486: . maxFails - maximum of unsuccessful steps
488: Level: intermediate
490: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
491: @*/
492: PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
493: {
497: *maxFails = snes->maxFailures;
498: return(0);
499: }
503: /*@
504: SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
505: linear solvers.
507: Not Collective
509: Input Parameter:
510: . snes - SNES context
512: Output Parameter:
513: . nfails - number of failed solves
515: Notes:
516: This counter is reset to zero for each successive call to SNESSolve().
518: Level: intermediate
520: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
521: @*/
522: PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
523: {
527: *nfails = snes->numLinearSolveFailures;
528: return(0);
529: }
533: /*@
534: SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
535: allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
537: Collective on SNES
539: Input Parameters:
540: + snes - SNES context
541: - maxFails - maximum allowed linear solve failures
543: Level: intermediate
545: Notes: By default this is 1; that is SNES returns on the first failed linear solve
547: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
549: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
550: @*/
551: PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
552: {
555: snes->maxLinearSolveFailures = maxFails;
556: return(0);
557: }
561: /*@
562: SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
563: are allowed before SNES terminates
565: Not Collective
567: Input Parameter:
568: . snes - SNES context
570: Output Parameter:
571: . maxFails - maximum of unsuccessful solves allowed
573: Level: intermediate
575: Notes: By default this is 1; that is SNES returns on the first failed linear solve
577: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
579: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
580: @*/
581: PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
582: {
586: *maxFails = snes->maxLinearSolveFailures;
587: return(0);
588: }
592: /*@
593: SNESGetLinearSolveIterations - Gets the total number of linear iterations
594: used by the nonlinear solver.
596: Not Collective
598: Input Parameter:
599: . snes - SNES context
601: Output Parameter:
602: . lits - number of linear iterations
604: Notes:
605: This counter is reset to zero for each successive call to SNESSolve().
607: Level: intermediate
609: .keywords: SNES, nonlinear, get, number, linear, iterations
611: .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm()
612: @*/
613: PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
614: {
618: *lits = snes->linear_its;
619: return(0);
620: }
624: /*@
625: SNESGetKSP - Returns the KSP context for a SNES solver.
627: Not Collective, but if SNES object is parallel, then KSP object is parallel
629: Input Parameter:
630: . snes - the SNES context
632: Output Parameter:
633: . ksp - the KSP context
635: Notes:
636: The user can then directly manipulate the KSP context to set various
637: options, etc. Likewise, the user can then extract and manipulate the
638: PC contexts as well.
640: Level: beginner
642: .keywords: SNES, nonlinear, get, KSP, context
644: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
645: @*/
646: PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp)
647: {
651: *ksp = snes->ksp;
652: return(0);
653: }
657: /*@
658: SNESSetKSP - Sets a KSP context for the SNES object to use
660: Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
662: Input Parameters:
663: + snes - the SNES context
664: - ksp - the KSP context
666: Notes:
667: The SNES object already has its KSP object, you can obtain with SNESGetKSP()
668: so this routine is rarely needed.
670: The KSP object that is already in the SNES object has its reference count
671: decreased by one.
673: Level: developer
675: .keywords: SNES, nonlinear, get, KSP, context
677: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
678: @*/
679: PetscErrorCode SNESSetKSP(SNES snes,KSP ksp)
680: {
687: PetscObjectReference((PetscObject)ksp);
688: if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
689: snes->ksp = ksp;
690: return(0);
691: }
695: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
696: {
698: return(0);
699: }
701: /* -----------------------------------------------------------*/
704: /*@
705: SNESCreate - Creates a nonlinear solver context.
707: Collective on MPI_Comm
709: Input Parameters:
710: . comm - MPI communicator
712: Output Parameter:
713: . outsnes - the new SNES context
715: Options Database Keys:
716: + -snes_mf - Activates default matrix-free Jacobian-vector products,
717: and no preconditioning matrix
718: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
719: products, and a user-provided preconditioning matrix
720: as set by SNESSetJacobian()
721: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
723: Level: beginner
725: .keywords: SNES, nonlinear, create, context
727: .seealso: SNESSolve(), SNESDestroy(), SNES
728: @*/
729: PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes)
730: {
731: PetscErrorCode ierr;
732: SNES snes;
733: SNESKSPEW *kctx;
737: *outsnes = PETSC_NULL;
738: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
739: SNESInitializePackage(PETSC_NULL);
740: #endif
742: PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
743: snes->bops->publish = SNESPublish_Petsc;
744: snes->max_its = 50;
745: snes->max_funcs = 10000;
746: snes->norm = 0.0;
747: snes->rtol = 1.e-8;
748: snes->ttol = 0.0;
749: snes->abstol = 1.e-50;
750: snes->xtol = 1.e-8;
751: snes->deltatol = 1.e-12;
752: snes->nfuncs = 0;
753: snes->numFailures = 0;
754: snes->maxFailures = 1;
755: snes->linear_its = 0;
756: snes->numbermonitors = 0;
757: snes->data = 0;
758: snes->setupcalled = PETSC_FALSE;
759: snes->ksp_ewconv = PETSC_FALSE;
760: snes->vwork = 0;
761: snes->nwork = 0;
762: snes->conv_hist_len = 0;
763: snes->conv_hist_max = 0;
764: snes->conv_hist = PETSC_NULL;
765: snes->conv_hist_its = PETSC_NULL;
766: snes->conv_hist_reset = PETSC_TRUE;
767: snes->reason = SNES_CONVERGED_ITERATING;
769: snes->numLinearSolveFailures = 0;
770: snes->maxLinearSolveFailures = 1;
772: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
773: PetscNew(SNESKSPEW,&kctx);
774: PetscLogObjectMemory(snes,sizeof(SNESKSPEW));
775: snes->kspconvctx = (void*)kctx;
776: kctx->version = 2;
777: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
778: this was too large for some test cases */
779: kctx->rtol_last = 0;
780: kctx->rtol_max = .9;
781: kctx->gamma = 1.0;
782: kctx->alpha = .5*(1.0 + sqrt(5.0));
783: kctx->alpha2 = kctx->alpha;
784: kctx->threshold = .1;
785: kctx->lresid_last = 0;
786: kctx->norm_last = 0;
788: KSPCreate(comm,&snes->ksp);
789: PetscLogObjectParent(snes,snes->ksp);
791: *outsnes = snes;
792: PetscPublishAll(snes);
793: return(0);
794: }
798: /*@C
799: SNESSetFunction - Sets the function evaluation routine and function
800: vector for use by the SNES routines in solving systems of nonlinear
801: equations.
803: Collective on SNES
805: Input Parameters:
806: + snes - the SNES context
807: . r - vector to store function value
808: . func - function evaluation routine
809: - ctx - [optional] user-defined context for private data for the
810: function evaluation routine (may be PETSC_NULL)
812: Calling sequence of func:
813: $ func (SNES snes,Vec x,Vec f,void *ctx);
815: . f - function vector
816: - ctx - optional user-defined function context
818: Notes:
819: The Newton-like methods typically solve linear systems of the form
820: $ f'(x) x = -f(x),
821: where f'(x) denotes the Jacobian matrix and f(x) is the function.
823: Level: beginner
825: .keywords: SNES, nonlinear, set, function
827: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
828: @*/
829: PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
830: {
836: snes->ops->computefunction = func;
837: snes->vec_func = snes->vec_func_always = r;
838: snes->funP = ctx;
839: return(0);
840: }
842: /* --------------------------------------------------------------- */
845: /*@C
846: SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set
847: it assumes a zero right hand side.
849: Collective on SNES
851: Input Parameters:
852: + snes - the SNES context
853: - rhs - the right hand side vector or PETSC_NULL for a zero right hand side
855: Level: intermediate
857: .keywords: SNES, nonlinear, set, function, right hand side
859: .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
860: @*/
861: PetscErrorCode SNESSetRhs(SNES snes,Vec rhs)
862: {
867: if (rhs) {
870: PetscObjectReference((PetscObject)rhs);
871: }
872: if (snes->afine) {
873: VecDestroy(snes->afine);
874: }
875: snes->afine = rhs;
876: return(0);
877: }
881: /*@C
882: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
883: it assumes a zero right hand side.
885: Collective on SNES
887: Input Parameter:
888: . snes - the SNES context
890: Output Parameter:
891: . rhs - the right hand side vector or PETSC_NULL for a zero right hand side
893: Level: intermediate
895: .keywords: SNES, nonlinear, get, function, right hand side
897: .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
898: @*/
899: PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs)
900: {
904: *rhs = snes->afine;
905: return(0);
906: }
910: /*@
911: SNESComputeFunction - Calls the function that has been set with
912: SNESSetFunction().
914: Collective on SNES
916: Input Parameters:
917: + snes - the SNES context
918: - x - input vector
920: Output Parameter:
921: . y - function vector, as set by SNESSetFunction()
923: Notes:
924: SNESComputeFunction() is typically used within nonlinear solvers
925: implementations, so most users would not generally call this routine
926: themselves.
928: Level: developer
930: .keywords: SNES, nonlinear, compute, function
932: .seealso: SNESSetFunction(), SNESGetFunction()
933: @*/
934: PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y)
935: {
946: if (snes->ops->computefunction) {
947: PetscStackPush("SNES user function");
948: CHKMEMQ;
949: (*snes->ops->computefunction)(snes,x,y,snes->funP);
950: CHKMEMQ;
951: PetscStackPop;
952: if (PetscExceptionValue(ierr)) {
954: }
955:
956: } else if (snes->afine) {
957: MatMult(snes->jacobian, x, y);
958: } else {
959: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
960: }
961: if (snes->afine) {
962: VecAXPY(y,-1.0,snes->afine);
963: }
964: snes->nfuncs++;
966: return(0);
967: }
971: /*@
972: SNESComputeJacobian - Computes the Jacobian matrix that has been
973: set with SNESSetJacobian().
975: Collective on SNES and Mat
977: Input Parameters:
978: + snes - the SNES context
979: - x - input vector
981: Output Parameters:
982: + A - Jacobian matrix
983: . B - optional preconditioning matrix
984: - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
986: Notes:
987: Most users should not need to explicitly call this routine, as it
988: is used internally within the nonlinear solvers.
990: See KSPSetOperators() for important information about setting the
991: flag parameter.
993: Level: developer
995: .keywords: SNES, compute, Jacobian, matrix
997: .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure
998: @*/
999: PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1000: {
1008: if (!snes->ops->computejacobian) return(0);
1010: *flg = DIFFERENT_NONZERO_PATTERN;
1011: PetscStackPush("SNES user Jacobian function");
1012: CHKMEMQ;
1013: (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1014: CHKMEMQ;
1015: PetscStackPop;
1017: /* make sure user returned a correct Jacobian and preconditioner */
1020: return(0);
1021: }
1025: /*@C
1026: SNESSetJacobian - Sets the function to compute Jacobian as well as the
1027: location to store the matrix.
1029: Collective on SNES and Mat
1031: Input Parameters:
1032: + snes - the SNES context
1033: . A - Jacobian matrix
1034: . B - preconditioner matrix (usually same as the Jacobian)
1035: . func - Jacobian evaluation routine
1036: - ctx - [optional] user-defined context for private data for the
1037: Jacobian evaluation routine (may be PETSC_NULL)
1039: Calling sequence of func:
1040: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
1042: + x - input vector
1043: . A - Jacobian matrix
1044: . B - preconditioner matrix, usually the same as A
1045: . flag - flag indicating information about the preconditioner matrix
1046: structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1047: - ctx - [optional] user-defined Jacobian context
1049: Notes:
1050: See KSPSetOperators() for important information about setting the flag
1051: output parameter in the routine func(). Be sure to read this information!
1053: The routine func() takes Mat * as the matrix arguments rather than Mat.
1054: This allows the Jacobian evaluation routine to replace A and/or B with a
1055: completely new new matrix structure (not just different matrix elements)
1056: when appropriate, for instance, if the nonzero structure is changing
1057: throughout the global iterations.
1059: Level: beginner
1061: .keywords: SNES, nonlinear, set, Jacobian, matrix
1063: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1064: @*/
1065: PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1066: {
1075: if (func) snes->ops->computejacobian = func;
1076: if (ctx) snes->jacP = ctx;
1077: if (A) {
1078: PetscObjectReference((PetscObject)A);
1079: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1080: snes->jacobian = A;
1081: }
1082: if (B) {
1083: PetscObjectReference((PetscObject)B);
1084: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1085: snes->jacobian_pre = B;
1086: }
1087: return(0);
1088: }
1092: /*@C
1093: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1094: provided context for evaluating the Jacobian.
1096: Not Collective, but Mat object will be parallel if SNES object is
1098: Input Parameter:
1099: . snes - the nonlinear solver context
1101: Output Parameters:
1102: + A - location to stash Jacobian matrix (or PETSC_NULL)
1103: . B - location to stash preconditioner matrix (or PETSC_NULL)
1104: . func - location to put Jacobian function (or PETSC_NULL)
1105: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
1107: Level: advanced
1109: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1110: @*/
1111: PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1112: {
1115: if (A) *A = snes->jacobian;
1116: if (B) *B = snes->jacobian_pre;
1117: if (func) *func = snes->ops->computejacobian;
1118: if (ctx) *ctx = snes->jacP;
1119: return(0);
1120: }
1122: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1123: EXTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
1127: /*@
1128: SNESSetUp - Sets up the internal data structures for the later use
1129: of a nonlinear solver.
1131: Collective on SNES
1133: Input Parameters:
1134: . snes - the SNES context
1136: Notes:
1137: For basic use of the SNES solvers the user need not explicitly call
1138: SNESSetUp(), since these actions will automatically occur during
1139: the call to SNESSolve(). However, if one wishes to control this
1140: phase separately, SNESSetUp() should be called after SNESCreate()
1141: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1143: Level: advanced
1145: .keywords: SNES, nonlinear, setup
1147: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1148: @*/
1149: PetscErrorCode SNESSetUp(SNES snes)
1150: {
1152: PetscTruth flg;
1156: if (snes->setupcalled) return(0);
1158: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
1159: /*
1160: This version replaces the user provided Jacobian matrix with a
1161: matrix-free version but still employs the user-provided preconditioner matrix
1162: */
1163: if (flg) {
1164: Mat J;
1165: MatCreateSNESMF(snes,&J);
1166: MatMFFDSetFromOptions(J);
1167: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1168: SNESSetJacobian(snes,J,0,0,0);
1169: MatDestroy(J);
1170: }
1172: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1173: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
1174: if (flg) {
1175: Mat J;
1176: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1177: PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");
1178: SNESSetJacobian(snes,J,0,0,0);
1179: MatDestroy(J);
1180: }
1181: #endif
1183: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
1184: /*
1185: This version replaces both the user-provided Jacobian and the user-
1186: provided preconditioner matrix with the default matrix free version.
1187: */
1188: if (flg) {
1189: Mat J;
1190: KSP ksp;
1191: PC pc;
1192: /* create and set matrix-free operator */
1193: MatCreateSNESMF(snes,&J);
1194: MatMFFDSetFromOptions(J);
1195: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1196: SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1197: MatDestroy(J);
1198: /* force no preconditioner */
1199: SNESGetKSP(snes,&ksp);
1200: KSPGetPC(ksp,&pc);
1201: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1202: if (!flg) {
1203: PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");
1204: PCSetType(pc,PCNONE);
1205: }
1206: }
1208: if (!snes->vec_func && !snes->afine) {
1209: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1210: }
1211: if (!snes->ops->computefunction && !snes->afine) {
1212: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1213: }
1214: if (!snes->jacobian) {
1215: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1216: }
1217: if (snes->vec_func == snes->vec_sol) {
1218: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1219: }
1221: if (!snes->type_name) {
1222: SNESSetType(snes,SNESLS);
1223: }
1224: if (snes->ops->setup) {
1225: (*snes->ops->setup)(snes);
1226: }
1227: snes->setupcalled = PETSC_TRUE;
1228: return(0);
1229: }
1233: /*@
1234: SNESDestroy - Destroys the nonlinear solver context that was created
1235: with SNESCreate().
1237: Collective on SNES
1239: Input Parameter:
1240: . snes - the SNES context
1242: Level: beginner
1244: .keywords: SNES, nonlinear, destroy
1246: .seealso: SNESCreate(), SNESSolve()
1247: @*/
1248: PetscErrorCode SNESDestroy(SNES snes)
1249: {
1254: if (--snes->refct > 0) return(0);
1256: /* if memory was published with AMS then destroy it */
1257: PetscObjectDepublish(snes);
1259: if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1260: PetscFree(snes->kspconvctx);
1261: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1262: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1263: if (snes->afine) {VecDestroy(snes->afine);}
1264: KSPDestroy(snes->ksp);
1265: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1266: SNESMonitorCancel(snes);
1267: PetscHeaderDestroy(snes);
1268: return(0);
1269: }
1271: /* ----------- Routines to set solver parameters ---------- */
1275: /*@
1276: SNESSetTolerances - Sets various parameters used in convergence tests.
1278: Collective on SNES
1280: Input Parameters:
1281: + snes - the SNES context
1282: . abstol - absolute convergence tolerance
1283: . rtol - relative convergence tolerance
1284: . stol - convergence tolerance in terms of the norm
1285: of the change in the solution between steps
1286: . maxit - maximum number of iterations
1287: - maxf - maximum number of function evaluations
1289: Options Database Keys:
1290: + -snes_atol <abstol> - Sets abstol
1291: . -snes_rtol <rtol> - Sets rtol
1292: . -snes_stol <stol> - Sets stol
1293: . -snes_max_it <maxit> - Sets maxit
1294: - -snes_max_funcs <maxf> - Sets maxf
1296: Notes:
1297: The default maximum number of iterations is 50.
1298: The default maximum number of function evaluations is 1000.
1300: Level: intermediate
1302: .keywords: SNES, nonlinear, set, convergence, tolerances
1304: .seealso: SNESSetTrustRegionTolerance()
1305: @*/
1306: PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1307: {
1310: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1311: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1312: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1313: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1314: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1315: return(0);
1316: }
1320: /*@
1321: SNESGetTolerances - Gets various parameters used in convergence tests.
1323: Not Collective
1325: Input Parameters:
1326: + snes - the SNES context
1327: . abstol - absolute convergence tolerance
1328: . rtol - relative convergence tolerance
1329: . stol - convergence tolerance in terms of the norm
1330: of the change in the solution between steps
1331: . maxit - maximum number of iterations
1332: - maxf - maximum number of function evaluations
1334: Notes:
1335: The user can specify PETSC_NULL for any parameter that is not needed.
1337: Level: intermediate
1339: .keywords: SNES, nonlinear, get, convergence, tolerances
1341: .seealso: SNESSetTolerances()
1342: @*/
1343: PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *abstol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1344: {
1347: if (abstol) *abstol = snes->abstol;
1348: if (rtol) *rtol = snes->rtol;
1349: if (stol) *stol = snes->xtol;
1350: if (maxit) *maxit = snes->max_its;
1351: if (maxf) *maxf = snes->max_funcs;
1352: return(0);
1353: }
1357: /*@
1358: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1360: Collective on SNES
1362: Input Parameters:
1363: + snes - the SNES context
1364: - tol - tolerance
1365:
1366: Options Database Key:
1367: . -snes_trtol <tol> - Sets tol
1369: Level: intermediate
1371: .keywords: SNES, nonlinear, set, trust region, tolerance
1373: .seealso: SNESSetTolerances()
1374: @*/
1375: PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1376: {
1379: snes->deltatol = tol;
1380: return(0);
1381: }
1383: /*
1384: Duplicate the lg monitors for SNES from KSP; for some reason with
1385: dynamic libraries things don't work under Sun4 if we just use
1386: macros instead of functions
1387: */
1390: PetscErrorCode SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1391: {
1396: KSPMonitorLG((KSP)snes,it,norm,ctx);
1397: return(0);
1398: }
1402: PetscErrorCode SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1403: {
1407: KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1408: return(0);
1409: }
1413: PetscErrorCode SNESMonitorLGDestroy(PetscDrawLG draw)
1414: {
1418: KSPMonitorLGDestroy(draw);
1419: return(0);
1420: }
1422: /* ------------ Routines to set performance monitoring options ----------- */
1426: /*@C
1427: SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1428: iteration of the nonlinear solver to display the iteration's
1429: progress.
1431: Collective on SNES
1433: Input Parameters:
1434: + snes - the SNES context
1435: . func - monitoring routine
1436: . mctx - [optional] user-defined context for private data for the
1437: monitor routine (use PETSC_NULL if no context is desired)
1438: - monitordestroy - [optional] routine that frees monitor context
1439: (may be PETSC_NULL)
1441: Calling sequence of func:
1442: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1444: + snes - the SNES context
1445: . its - iteration number
1446: . norm - 2-norm function value (may be estimated)
1447: - mctx - [optional] monitoring context
1449: Options Database Keys:
1450: + -snes_monitor - sets SNESMonitorDefault()
1451: . -snes_monitor_draw - sets line graph monitor,
1452: uses SNESMonitorLGCreate()
1453: _ -snes_monitor_cancel - cancels all monitors that have
1454: been hardwired into a code by
1455: calls to SNESMonitorSet(), but
1456: does not cancel those set via
1457: the options database.
1459: Notes:
1460: Several different monitoring routines may be set by calling
1461: SNESMonitorSet() multiple times; all will be called in the
1462: order in which they were set.
1464: Level: intermediate
1466: .keywords: SNES, nonlinear, set, monitor
1468: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1469: @*/
1470: PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1471: {
1472: PetscInt i;
1476: if (snes->numbermonitors >= MAXSNESMONITORS) {
1477: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1478: }
1479: for (i=0; i<snes->numbermonitors;i++) {
1480: if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);
1482: /* check if both default monitors that share common ASCII viewer */
1483: if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1484: if (mctx && snes->monitorcontext[i]) {
1485: PetscErrorCode ierr;
1486: PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1487: PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1488: if (viewer1->viewer == viewer2->viewer) {
1489: (*monitordestroy)(mctx);
1490: return(0);
1491: }
1492: }
1493: }
1494: }
1495: snes->monitor[snes->numbermonitors] = monitor;
1496: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1497: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1498: return(0);
1499: }
1503: /*@C
1504: SNESMonitorCancel - Clears all the monitor functions for a SNES object.
1506: Collective on SNES
1508: Input Parameters:
1509: . snes - the SNES context
1511: Options Database Key:
1512: . -snes_monitor_cancel - cancels all monitors that have been hardwired
1513: into a code by calls to SNESMonitorSet(), but does not cancel those
1514: set via the options database
1516: Notes:
1517: There is no way to clear one specific monitor from a SNES object.
1519: Level: intermediate
1521: .keywords: SNES, nonlinear, set, monitor
1523: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1524: @*/
1525: PetscErrorCode SNESMonitorCancel(SNES snes)
1526: {
1528: PetscInt i;
1532: for (i=0; i<snes->numbermonitors; i++) {
1533: if (snes->monitordestroy[i]) {
1534: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1535: }
1536: }
1537: snes->numbermonitors = 0;
1538: return(0);
1539: }
1543: /*@C
1544: SNESSetConvergenceTest - Sets the function that is to be used
1545: to test for convergence of the nonlinear iterative solution.
1547: Collective on SNES
1549: Input Parameters:
1550: + snes - the SNES context
1551: . func - routine to test for convergence
1552: - cctx - [optional] context for private data for the convergence routine
1553: (may be PETSC_NULL)
1555: Calling sequence of func:
1556: $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1558: + snes - the SNES context
1559: . it - current iteration (0 is the first and is before any Newton step)
1560: . cctx - [optional] convergence context
1561: . reason - reason for convergence/divergence
1562: . xnorm - 2-norm of current iterate
1563: . gnorm - 2-norm of current step
1564: - f - 2-norm of function
1566: Level: advanced
1568: .keywords: SNES, nonlinear, set, convergence, test
1570: .seealso: SNESDefaultConverged(), SNESSkipConverged(), SNESConverged_LS(), SNESConverged_TR()
1571: @*/
1572: PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1573: {
1576: (snes)->ops->converged = func;
1577: (snes)->cnvP = cctx;
1578: return(0);
1579: }
1583: /*@
1584: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1586: Not Collective
1588: Input Parameter:
1589: . snes - the SNES context
1591: Output Parameter:
1592: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1593: manual pages for the individual convergence tests for complete lists
1595: Level: intermediate
1597: Notes: Can only be called after the call the SNESSolve() is complete.
1599: .keywords: SNES, nonlinear, set, convergence, test
1601: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1602: @*/
1603: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1604: {
1608: *reason = snes->reason;
1609: return(0);
1610: }
1614: /*@
1615: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1617: Collective on SNES
1619: Input Parameters:
1620: + snes - iterative context obtained from SNESCreate()
1621: . a - array to hold history
1622: . its - integer array holds the number of linear iterations for each solve.
1623: . na - size of a and its
1624: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1625: else it continues storing new values for new nonlinear solves after the old ones
1627: Notes:
1628: If set, this array will contain the function norms computed
1629: at each step.
1631: This routine is useful, e.g., when running a code for purposes
1632: of accurate performance monitoring, when no I/O should be done
1633: during the section of code that is being timed.
1635: Level: intermediate
1637: .keywords: SNES, set, convergence, history
1639: .seealso: SNESGetConvergenceHistory()
1641: @*/
1642: PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
1643: {
1648: snes->conv_hist = a;
1649: snes->conv_hist_its = its;
1650: snes->conv_hist_max = na;
1651: snes->conv_hist_reset = reset;
1652: return(0);
1653: }
1657: /*@C
1658: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1660: Collective on SNES
1662: Input Parameter:
1663: . snes - iterative context obtained from SNESCreate()
1665: Output Parameters:
1666: . a - array to hold history
1667: . its - integer array holds the number of linear iterations (or
1668: negative if not converged) for each solve.
1669: - na - size of a and its
1671: Notes:
1672: The calling sequence for this routine in Fortran is
1673: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1675: This routine is useful, e.g., when running a code for purposes
1676: of accurate performance monitoring, when no I/O should be done
1677: during the section of code that is being timed.
1679: Level: intermediate
1681: .keywords: SNES, get, convergence, history
1683: .seealso: SNESSetConvergencHistory()
1685: @*/
1686: PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1687: {
1690: if (a) *a = snes->conv_hist;
1691: if (its) *its = snes->conv_hist_its;
1692: if (na) *na = snes->conv_hist_len;
1693: return(0);
1694: }
1698: /*@C
1699: SNESSetUpdate - Sets the general-purpose update function called
1700: at the beginning o every iteration of the nonlinear solve. Specifically
1701: it is called just before the Jacobian is "evaluated".
1703: Collective on SNES
1705: Input Parameters:
1706: . snes - The nonlinear solver context
1707: . func - The function
1709: Calling sequence of func:
1710: . func (SNES snes, PetscInt step);
1712: . step - The current step of the iteration
1714: Level: intermediate
1716: .keywords: SNES, update
1718: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1719: @*/
1720: PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1721: {
1724: snes->ops->update = func;
1725: return(0);
1726: }
1730: /*@
1731: SNESDefaultUpdate - The default update function which does nothing.
1733: Not collective
1735: Input Parameters:
1736: . snes - The nonlinear solver context
1737: . step - The current step of the iteration
1739: Level: intermediate
1741: .keywords: SNES, update
1742: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
1743: @*/
1744: PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step)
1745: {
1747: return(0);
1748: }
1752: /*
1753: SNESScaleStep_Private - Scales a step so that its length is less than the
1754: positive parameter delta.
1756: Input Parameters:
1757: + snes - the SNES context
1758: . y - approximate solution of linear system
1759: . fnorm - 2-norm of current function
1760: - delta - trust region size
1762: Output Parameters:
1763: + gpnorm - predicted function norm at the new point, assuming local
1764: linearization. The value is zero if the step lies within the trust
1765: region, and exceeds zero otherwise.
1766: - ynorm - 2-norm of the step
1768: Note:
1769: For non-trust region methods such as SNESLS, the parameter delta
1770: is set to be the maximum allowable step size.
1772: .keywords: SNES, nonlinear, scale, step
1773: */
1774: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1775: {
1776: PetscReal nrm;
1777: PetscScalar cnorm;
1785: VecNorm(y,NORM_2,&nrm);
1786: if (nrm > *delta) {
1787: nrm = *delta/nrm;
1788: *gpnorm = (1.0 - nrm)*(*fnorm);
1789: cnorm = nrm;
1790: VecScale(y,cnorm);
1791: *ynorm = *delta;
1792: } else {
1793: *gpnorm = 0.0;
1794: *ynorm = nrm;
1795: }
1796: return(0);
1797: }
1801: /*@C
1802: SNESSolve - Solves a nonlinear system F(x) = b.
1803: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
1805: Collective on SNES
1807: Input Parameters:
1808: + snes - the SNES context
1809: . b - the constant part of the equation, or PETSC_NULL to use zero.
1810: - x - the solution vector, or PETSC_NULL if it was set with SNESSetSolution()
1812: Notes:
1813: The user should initialize the vector,x, with the initial guess
1814: for the nonlinear solve prior to calling SNESSolve. In particular,
1815: to employ an initial guess of zero, the user should explicitly set
1816: this vector to zero by calling VecSet().
1818: Level: beginner
1820: .keywords: SNES, nonlinear, solve
1822: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetRhs(), SNESSetSolution()
1823: @*/
1824: PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x)
1825: {
1827: PetscTruth flg;
1828: char filename[PETSC_MAX_PATH_LEN];
1829: PetscViewer viewer;
1833: if (!snes->ops->solve) SETERRQ(PETSC_ERR_ORDER,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1835: if (b) {
1836: SNESSetRhs(snes, b);
1837: if (!snes->vec_func) {
1838: Vec r;
1840: VecDuplicate(b, &r);
1841: SNESSetFunction(snes, r, PETSC_NULL, PETSC_NULL);
1842: }
1843: }
1844: if (x) {
1847: } else {
1848: SNESGetSolution(snes, &x);
1849: if (!x) {
1850: VecDuplicate(snes->vec_func_always, &x);
1851: }
1852: }
1853: snes->vec_sol = snes->vec_sol_always = x;
1855: SNESSetUp(snes);
1857: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1858: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1861:
1862: PetscExceptionTry1((*(snes)->ops->solve)(snes),PETSC_ERR_ARG_DOMAIN);
1863: if (PetscExceptionValue(ierr)) {
1864: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
1866: } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) {
1867: /* translate exception into SNES not converged reason */
1868: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
1869: 0;
1870: }
1871:
1872: if (!snes->reason) {
1873: SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
1874: }
1875: if (!snes->ops->converged && snes->reason == SNES_DIVERGED_MAX_IT) {
1876: snes->reason = SNES_CONVERGED_ITS;
1877: }
1879:
1880: PetscOptionsGetString(snes->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
1881: if (flg && !PetscPreLoadingOn) {
1882: PetscViewerASCIIOpen(snes->comm,filename,&viewer);
1883: SNESView(snes,viewer);
1884: PetscViewerDestroy(viewer);
1885: }
1887: PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);
1888: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1889: if (snes->printreason) {
1890: if (snes->reason > 0) {
1891: PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1892: } else {
1893: PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1894: }
1895: }
1897: return(0);
1898: }
1900: /* --------- Internal routines for SNES Package --------- */
1904: /*@C
1905: SNESSetType - Sets the method for the nonlinear solver.
1907: Collective on SNES
1909: Input Parameters:
1910: + snes - the SNES context
1911: - type - a known method
1913: Options Database Key:
1914: . -snes_type <type> - Sets the method; use -help for a list
1915: of available methods (for instance, ls or tr)
1917: Notes:
1918: See "petsc/include/petscsnes.h" for available methods (for instance)
1919: + SNESLS - Newton's method with line search
1920: (systems of nonlinear equations)
1921: . SNESTR - Newton's method with trust region
1922: (systems of nonlinear equations)
1924: Normally, it is best to use the SNESSetFromOptions() command and then
1925: set the SNES solver type from the options database rather than by using
1926: this routine. Using the options database provides the user with
1927: maximum flexibility in evaluating the many nonlinear solvers.
1928: The SNESSetType() routine is provided for those situations where it
1929: is necessary to set the nonlinear solver independently of the command
1930: line or options database. This might be the case, for example, when
1931: the choice of solver changes during the execution of the program,
1932: and the user's application is taking responsibility for choosing the
1933: appropriate method.
1935: Level: intermediate
1937: .keywords: SNES, set, type
1939: .seealso: SNESType, SNESCreate()
1941: @*/
1942: PetscErrorCode SNESSetType(SNES snes,SNESType type)
1943: {
1944: PetscErrorCode ierr,(*r)(SNES);
1945: PetscTruth match;
1951: PetscTypeCompare((PetscObject)snes,type,&match);
1952: if (match) return(0);
1954: PetscFListFind(SNESList,snes->comm,type,(void (**)(void)) &r);
1955: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1956: /* Destroy the previous private SNES context */
1957: if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
1958: /* Reinitialize function pointers in SNESOps structure */
1959: snes->ops->converged = 0;
1960: snes->ops->setup = 0;
1961: snes->ops->solve = 0;
1962: snes->ops->view = 0;
1963: snes->ops->setfromoptions = 0;
1964: snes->ops->destroy = 0;
1965: /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
1966: snes->setupcalled = PETSC_FALSE;
1967: (*r)(snes);
1968: PetscObjectChangeTypeName((PetscObject)snes,type);
1969: return(0);
1970: }
1973: /* --------------------------------------------------------------------- */
1976: /*@
1977: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1978: registered by SNESRegisterDynamic().
1980: Not Collective
1982: Level: advanced
1984: .keywords: SNES, nonlinear, register, destroy
1986: .seealso: SNESRegisterAll(), SNESRegisterAll()
1987: @*/
1988: PetscErrorCode SNESRegisterDestroy(void)
1989: {
1993: PetscFListDestroy(&SNESList);
1994: SNESRegisterAllCalled = PETSC_FALSE;
1995: return(0);
1996: }
2000: /*@C
2001: SNESGetType - Gets the SNES method type and name (as a string).
2003: Not Collective
2005: Input Parameter:
2006: . snes - nonlinear solver context
2008: Output Parameter:
2009: . type - SNES method (a character string)
2011: Level: intermediate
2013: .keywords: SNES, nonlinear, get, type, name
2014: @*/
2015: PetscErrorCode SNESGetType(SNES snes,SNESType *type)
2016: {
2020: *type = snes->type_name;
2021: return(0);
2022: }
2026: /*@
2027: SNESGetSolution - Returns the vector where the approximate solution is
2028: stored.
2030: Not Collective, but Vec is parallel if SNES is parallel
2032: Input Parameter:
2033: . snes - the SNES context
2035: Output Parameter:
2036: . x - the solution
2038: Level: intermediate
2040: .keywords: SNES, nonlinear, get, solution
2042: .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
2043: @*/
2044: PetscErrorCode SNESGetSolution(SNES snes,Vec *x)
2045: {
2049: *x = snes->vec_sol_always;
2050: return(0);
2051: }
2055: /*@
2056: SNESSetSolution - Sets the vector where the approximate solution is stored.
2058: Not Collective, but Vec is parallel if SNES is parallel
2060: Input Parameters:
2061: + snes - the SNES context
2062: - x - the solution
2064: Output Parameter:
2066: Level: intermediate
2068: Notes: this is not normally used, rather one simply calls SNESSolve() with
2069: the appropriate solution vector.
2071: .keywords: SNES, nonlinear, set, solution
2073: .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
2074: @*/
2075: PetscErrorCode SNESSetSolution(SNES snes,Vec x)
2076: {
2081: snes->vec_sol_always = x;
2082: return(0);
2083: }
2087: /*@
2088: SNESGetSolutionUpdate - Returns the vector where the solution update is
2089: stored.
2091: Not Collective, but Vec is parallel if SNES is parallel
2093: Input Parameter:
2094: . snes - the SNES context
2096: Output Parameter:
2097: . x - the solution update
2099: Level: advanced
2101: .keywords: SNES, nonlinear, get, solution, update
2103: .seealso: SNESGetSolution(), SNESGetFunction
2104: @*/
2105: PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x)
2106: {
2110: *x = snes->vec_sol_update_always;
2111: return(0);
2112: }
2116: /*@C
2117: SNESGetFunction - Returns the vector where the function is stored.
2119: Not Collective, but Vec is parallel if SNES is parallel
2121: Input Parameter:
2122: . snes - the SNES context
2124: Output Parameter:
2125: + r - the function (or PETSC_NULL)
2126: . func - the function (or PETSC_NULL)
2127: - ctx - the function context (or PETSC_NULL)
2129: Level: advanced
2131: .keywords: SNES, nonlinear, get, function
2133: .seealso: SNESSetFunction(), SNESGetSolution()
2134: @*/
2135: PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2136: {
2139: if (r) *r = snes->vec_func_always;
2140: if (func) *func = snes->ops->computefunction;
2141: if (ctx) *ctx = snes->funP;
2142: return(0);
2143: }
2147: /*@C
2148: SNESSetOptionsPrefix - Sets the prefix used for searching for all
2149: SNES options in the database.
2151: Collective on SNES
2153: Input Parameter:
2154: + snes - the SNES context
2155: - prefix - the prefix to prepend to all option names
2157: Notes:
2158: A hyphen (-) must NOT be given at the beginning of the prefix name.
2159: The first character of all runtime options is AUTOMATICALLY the hyphen.
2161: Level: advanced
2163: .keywords: SNES, set, options, prefix, database
2165: .seealso: SNESSetFromOptions()
2166: @*/
2167: PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[])
2168: {
2173: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2174: KSPSetOptionsPrefix(snes->ksp,prefix);
2175: return(0);
2176: }
2180: /*@C
2181: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2182: SNES options in the database.
2184: Collective on SNES
2186: Input Parameters:
2187: + snes - the SNES context
2188: - prefix - the prefix to prepend to all option names
2190: Notes:
2191: A hyphen (-) must NOT be given at the beginning of the prefix name.
2192: The first character of all runtime options is AUTOMATICALLY the hyphen.
2194: Level: advanced
2196: .keywords: SNES, append, options, prefix, database
2198: .seealso: SNESGetOptionsPrefix()
2199: @*/
2200: PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2201: {
2203:
2206: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2207: KSPAppendOptionsPrefix(snes->ksp,prefix);
2208: return(0);
2209: }
2213: /*@C
2214: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2215: SNES options in the database.
2217: Not Collective
2219: Input Parameter:
2220: . snes - the SNES context
2222: Output Parameter:
2223: . prefix - pointer to the prefix string used
2225: Notes: On the fortran side, the user should pass in a string 'prifix' of
2226: sufficient length to hold the prefix.
2228: Level: advanced
2230: .keywords: SNES, get, options, prefix, database
2232: .seealso: SNESAppendOptionsPrefix()
2233: @*/
2234: PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2235: {
2240: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2241: return(0);
2242: }
2247: /*@C
2248: SNESRegister - See SNESRegisterDynamic()
2250: Level: advanced
2251: @*/
2252: PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2253: {
2254: char fullname[PETSC_MAX_PATH_LEN];
2258: PetscFListConcat(path,name,fullname);
2259: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2260: return(0);
2261: }
2265: PetscErrorCode SNESTestLocalMin(SNES snes)
2266: {
2268: PetscInt N,i,j;
2269: Vec u,uh,fh;
2270: PetscScalar value;
2271: PetscReal norm;
2274: SNESGetSolution(snes,&u);
2275: VecDuplicate(u,&uh);
2276: VecDuplicate(u,&fh);
2278: /* currently only works for sequential */
2279: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2280: VecGetSize(u,&N);
2281: for (i=0; i<N; i++) {
2282: VecCopy(u,uh);
2283: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2284: for (j=-10; j<11; j++) {
2285: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2286: VecSetValue(uh,i,value,ADD_VALUES);
2287: SNESComputeFunction(snes,uh,fh);
2288: VecNorm(fh,NORM_2,&norm);
2289: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2290: value = -value;
2291: VecSetValue(uh,i,value,ADD_VALUES);
2292: }
2293: }
2294: VecDestroy(uh);
2295: VecDestroy(fh);
2296: return(0);
2297: }
2301: /*@
2302: SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2303: computing relative tolerance for linear solvers within an inexact
2304: Newton method.
2306: Collective on SNES
2308: Input Parameters:
2309: + snes - SNES context
2310: - flag - PETSC_TRUE or PETSC_FALSE
2312: Notes:
2313: Currently, the default is to use a constant relative tolerance for
2314: the inner linear solvers. Alternatively, one can use the
2315: Eisenstat-Walker method, where the relative convergence tolerance
2316: is reset at each Newton iteration according progress of the nonlinear
2317: solver.
2319: Level: advanced
2321: Reference:
2322: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2323: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2325: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2327: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2328: @*/
2329: PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2330: {
2333: snes->ksp_ewconv = flag;
2334: return(0);
2335: }
2339: /*@
2340: SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2341: for computing relative tolerance for linear solvers within an
2342: inexact Newton method.
2344: Not Collective
2346: Input Parameter:
2347: . snes - SNES context
2349: Output Parameter:
2350: . flag - PETSC_TRUE or PETSC_FALSE
2352: Notes:
2353: Currently, the default is to use a constant relative tolerance for
2354: the inner linear solvers. Alternatively, one can use the
2355: Eisenstat-Walker method, where the relative convergence tolerance
2356: is reset at each Newton iteration according progress of the nonlinear
2357: solver.
2359: Level: advanced
2361: Reference:
2362: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2363: inexact Newton method", SISC 17 (1), pp.16-32, 1996.
2365: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton
2367: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2368: @*/
2369: PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2370: {
2374: *flag = snes->ksp_ewconv;
2375: return(0);
2376: }
2380: /*@
2381: SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2382: convergence criteria for the linear solvers within an inexact
2383: Newton method.
2385: Collective on SNES
2386:
2387: Input Parameters:
2388: + snes - SNES context
2389: . version - version 1, 2 (default is 2) or 3
2390: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2391: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2392: . gamma - multiplicative factor for version 2 rtol computation
2393: (0 <= gamma2 <= 1)
2394: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2395: . alpha2 - power for safeguard
2396: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2398: Note:
2399: Version 3 was contributed by Luis Chacon, June 2006.
2401: Use PETSC_DEFAULT to retain the default for any of the parameters.
2403: Level: advanced
2405: Reference:
2406: S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an
2407: inexact Newton method", Utah State University Math. Stat. Dept. Res.
2408: Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput.
2410: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters
2412: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2413: @*/
2414: PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2415: PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2416: {
2417: SNESKSPEW *kctx;
2420: kctx = (SNESKSPEW*)snes->kspconvctx;
2421: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2423: if (version != PETSC_DEFAULT) kctx->version = version;
2424: if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0;
2425: if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max;
2426: if (gamma != PETSC_DEFAULT) kctx->gamma = gamma;
2427: if (alpha != PETSC_DEFAULT) kctx->alpha = alpha;
2428: if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2;
2429: if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2430:
2431: if (kctx->version < 1 || kctx->version > 3) {
2432: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2433: }
2434: if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2435: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2436: }
2437: if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2438: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2439: }
2440: if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2441: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2442: }
2443: if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2444: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2445: }
2446: if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2447: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2448: }
2449: return(0);
2450: }
2454: /*@
2455: SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2456: convergence criteria for the linear solvers within an inexact
2457: Newton method.
2459: Not Collective
2460:
2461: Input Parameters:
2462: snes - SNES context
2464: Output Parameters:
2465: + version - version 1, 2 (default is 2) or 3
2466: . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2467: . rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2468: . gamma - multiplicative factor for version 2 rtol computation
2469: (0 <= gamma2 <= 1)
2470: . alpha - power for version 2 rtol computation (1 < alpha <= 2)
2471: . alpha2 - power for safeguard
2472: - threshold - threshold for imposing safeguard (0 < threshold < 1)
2474: Level: advanced
2476: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters
2478: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2479: @*/
2480: PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2481: PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2482: {
2483: SNESKSPEW *kctx;
2486: kctx = (SNESKSPEW*)snes->kspconvctx;
2487: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2488: if(version) *version = kctx->version;
2489: if(rtol_0) *rtol_0 = kctx->rtol_0;
2490: if(rtol_max) *rtol_max = kctx->rtol_max;
2491: if(gamma) *gamma = kctx->gamma;
2492: if(alpha) *alpha = kctx->alpha;
2493: if(alpha2) *alpha2 = kctx->alpha2;
2494: if(threshold) *threshold = kctx->threshold;
2495: return(0);
2496: }
2500: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2501: {
2503: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2504: PetscReal rtol=PETSC_DEFAULT,stol;
2507: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2508: if (!snes->iter) { /* first time in, so use the original user rtol */
2509: rtol = kctx->rtol_0;
2510: } else {
2511: if (kctx->version == 1) {
2512: rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2513: if (rtol < 0.0) rtol = -rtol;
2514: stol = pow(kctx->rtol_last,kctx->alpha2);
2515: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2516: } else if (kctx->version == 2) {
2517: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2518: stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2519: if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2520: } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2521: rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2522: /* safeguard: avoid sharp decrease of rtol */
2523: stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2524: stol = PetscMax(rtol,stol);
2525: rtol = PetscMin(kctx->rtol_0,stol);
2526: /* safeguard: avoid oversolving */
2527: stol = kctx->gamma*(snes->ttol)/snes->norm;
2528: stol = PetscMax(rtol,stol);
2529: rtol = PetscMin(kctx->rtol_0,stol);
2530: } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2531: }
2532: /* safeguard: avoid rtol greater than one */
2533: rtol = PetscMin(rtol,kctx->rtol_max);
2534: KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2535: PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2536: return(0);
2537: }
2541: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2542: {
2544: SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx;
2545: PCSide pcside;
2546: Vec lres;
2549: if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2550: KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2551: SNESGetFunctionNorm(snes,&kctx->norm_last);
2552: if (kctx->version == 1) {
2553: KSPGetPreconditionerSide(ksp,&pcside);
2554: if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2555: /* KSP residual is true linear residual */
2556: KSPGetResidualNorm(ksp,&kctx->lresid_last);
2557: } else {
2558: /* KSP residual is preconditioned residual */
2559: /* compute true linear residual norm */
2560: VecDuplicate(b,&lres);
2561: MatMult(snes->jacobian,x,lres);
2562: VecAYPX(lres,-1.0,b);
2563: VecNorm(lres,NORM_2,&kctx->lresid_last);
2564: VecDestroy(lres);
2565: }
2566: }
2567: return(0);
2568: }
2572: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2573: {
2577: if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x); }
2578: KSPSolve(ksp,b,x);
2579: if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2580: return(0);
2581: }