Actual source code: snes.c
1: #define PETSCSNES_DLL
3: #include src/snes/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: SNES_KSP_EW_ConvCtx *kctx;
46: PetscErrorCode ierr;
47: KSP ksp;
48: SNESType type;
49: PetscTruth iascii,isstring;
53: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
57: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
58: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
59: if (iascii) {
60: if (snes->prefix) {
61: PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",snes->prefix);
62: } else {
63: PetscViewerASCIIPrintf(viewer,"SNES Object:\n");
64: }
65: SNESGetType(snes,&type);
66: if (type) {
67: PetscViewerASCIIPrintf(viewer," type: %s\n",type);
68: } else {
69: PetscViewerASCIIPrintf(viewer," type: not set yet\n");
70: }
71: if (snes->ops->view) {
72: PetscViewerASCIIPushTab(viewer);
73: (*snes->ops->view)(snes,viewer);
74: PetscViewerASCIIPopTab(viewer);
75: }
76: PetscViewerASCIIPrintf(viewer," maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
77: PetscViewerASCIIPrintf(viewer," tolerances: relative=%G, absolute=%G, solution=%G\n",
78: snes->rtol,snes->abstol,snes->xtol);
79: PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%D\n",snes->linear_its);
80: PetscViewerASCIIPrintf(viewer," total number of function evaluations=%D\n",snes->nfuncs);
81: if (snes->ksp_ewconv) {
82: kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
83: if (kctx) {
84: PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
85: PetscViewerASCIIPrintf(viewer," rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
86: PetscViewerASCIIPrintf(viewer," gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
87: }
88: }
89: } else if (isstring) {
90: SNESGetType(snes,&type);
91: PetscViewerStringSPrintf(viewer," %-3.3s",type);
92: }
93: SNESGetKSP(snes,&ksp);
94: PetscViewerASCIIPushTab(viewer);
95: KSPView(ksp,viewer);
96: PetscViewerASCIIPopTab(viewer);
97: return(0);
98: }
100: /*
101: We retain a list of functions that also take SNES command
102: line options. These are called at the end SNESSetFromOptions()
103: */
104: #define MAXSETFROMOPTIONS 5
105: static PetscInt numberofsetfromoptions;
106: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
110: /*@C
111: SNESAddOptionsChecker - Adds an additional function to check for SNES options.
113: Not Collective
115: Input Parameter:
116: . snescheck - function that checks for options
118: Level: developer
120: .seealso: SNESSetFromOptions()
121: @*/
122: PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
123: {
125: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
126: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
127: }
128: othersetfromoptions[numberofsetfromoptions++] = snescheck;
129: return(0);
130: }
134: /*@
135: SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
137: Collective on SNES
139: Input Parameter:
140: . snes - the SNES context
142: Options Database Keys:
143: + -snes_type <type> - ls, tr, umls, umtr, test
144: . -snes_stol - convergence tolerance in terms of the norm
145: of the change in the solution between steps
146: . -snes_atol <abstol> - absolute tolerance of residual norm
147: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
148: . -snes_max_it <max_it> - maximum number of iterations
149: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
150: . -snes_max_fail <max_fail> - maximum number of failures
151: . -snes_trtol <trtol> - trust region tolerance
152: . -snes_no_convergence_test - skip convergence test in nonlinear
153: solver; hence iterations will continue until max_it
154: or some other criterion is reached. Saves expense
155: of convergence test
156: . -snes_monitor <optional filename> - prints residual norm at each iteration. if no
157: filename given prints to stdout
158: . -snes_vecmonitor - plots solution at each iteration
159: . -snes_vecmonitor_update - plots update to solution at each iteration
160: . -snes_xmonitor - plots residual norm at each iteration
161: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
162: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
163: - -snes_print_converged_reason - print the reason for convergence/divergence after each solve
165: Options Database for Eisenstat-Walker method:
166: + -snes_ksp_ew_conv - use Eisenstat-Walker method for determining linear system convergence
167: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
168: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
169: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
170: . -snes_ksp_ew_gamma <gamma> - Sets gamma
171: . -snes_ksp_ew_alpha <alpha> - Sets alpha
172: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
173: - -snes_ksp_ew_threshold <threshold> - Sets threshold
175: Notes:
176: To see all options, run your program with the -help option or consult
177: the users manual.
179: Level: beginner
181: .keywords: SNES, nonlinear, set, options, database
183: .seealso: SNESSetOptionsPrefix()
184: @*/
185: PetscErrorCode SNESSetFromOptions(SNES snes)
186: {
187: KSP ksp;
188: SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
189: PetscTruth flg;
190: PetscErrorCode ierr;
191: PetscInt i;
192: const char *deft;
193: char type[256], monfilename[PETSC_MAX_PATH_LEN];
194: PetscViewer monviewer;
199: PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");
200: if (snes->type_name) {
201: deft = snes->type_name;
202: } else {
203: deft = SNESLS;
204: }
206: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
207: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
208: if (flg) {
209: SNESSetType(snes,type);
210: } else if (!snes->type_name) {
211: SNESSetType(snes,deft);
212: }
213: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
215: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
216: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);
218: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
219: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
220: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
221: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
222: PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
223: if (flg) {
224: snes->printreason = PETSC_TRUE;
225: }
227: PetscOptionsTruth("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetParametersEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
229: PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);
230: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
231: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
232: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);
233: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);
234: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);
235: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);
237: PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);
238: if (flg) {snes->ops->converged = 0;}
239: PetscOptionsName("-snes_cancelmonitors","Remove all monitors","SNESClearMonitor",&flg);
240: if (flg) {SNESClearMonitor(snes);}
242: PetscOptionsString("-snes_monitor","Monitor norm of function","SNESSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
243: if (flg) {
244: PetscViewerASCIIOpen(snes->comm,monfilename,&monviewer);
245: SNESSetMonitor(snes,SNESDefaultMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
246: }
248: PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESSetRatioMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
249: if (flg) {
250: PetscViewerASCIIOpen(snes->comm,monfilename,&monviewer);
251: SNESSetRatioMonitor(snes,monviewer);
252: }
254: PetscOptionsString("-snes_smonitor","Monitor norm of function (fewer digits)","SNESSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
255: if (flg) {
256: PetscViewerASCIIOpen(snes->comm,monfilename,&monviewer);
257: SNESSetMonitor(snes,SNESDefaultSMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
258: }
260: PetscOptionsName("-snes_vecmonitor","Plot solution at each iteration","SNESVecViewMonitor",&flg);
261: if (flg) {SNESSetMonitor(snes,SNESVecViewMonitor,0,0);}
262: PetscOptionsName("-snes_vecmonitor_update","Plot correction at each iteration","SNESVecViewUpdateMonitor",&flg);
263: if (flg) {SNESSetMonitor(snes,SNESVecViewUpdateMonitor,0,0);}
264: PetscOptionsName("-snes_vecmonitor_residual","Plot residual at each iteration","SNESVecViewResidualMonitor",&flg);
265: if (flg) {SNESSetMonitor(snes,SNESVecViewResidualMonitor,0,0);}
266: PetscOptionsName("-snes_xmonitor","Plot function norm at each iteration","SNESLGMonitor",&flg);
267: if (flg) {SNESSetMonitor(snes,SNESLGMonitor,PETSC_NULL,PETSC_NULL);}
269: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
270: if (flg) {
271: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
272: PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
273: }
275: for(i = 0; i < numberofsetfromoptions; i++) {
276: (*othersetfromoptions[i])(snes);
277: }
279: if (snes->ops->setfromoptions) {
280: (*snes->ops->setfromoptions)(snes);
281: }
282: PetscOptionsEnd();
284: SNESGetKSP(snes,&ksp);
285: KSPSetFromOptions(ksp);
287: return(0);
288: }
293: /*@
294: SNESSetApplicationContext - Sets the optional user-defined context for
295: the nonlinear solvers.
297: Collective on SNES
299: Input Parameters:
300: + snes - the SNES context
301: - usrP - optional user context
303: Level: intermediate
305: .keywords: SNES, nonlinear, set, application, context
307: .seealso: SNESGetApplicationContext()
308: @*/
309: PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP)
310: {
313: snes->user = usrP;
314: return(0);
315: }
319: /*@C
320: SNESGetApplicationContext - Gets the user-defined context for the
321: nonlinear solvers.
323: Not Collective
325: Input Parameter:
326: . snes - SNES context
328: Output Parameter:
329: . usrP - user context
331: Level: intermediate
333: .keywords: SNES, nonlinear, get, application, context
335: .seealso: SNESSetApplicationContext()
336: @*/
337: PetscErrorCode SNESGetApplicationContext(SNES snes,void **usrP)
338: {
341: *usrP = snes->user;
342: return(0);
343: }
347: /*@
348: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
349: at this time.
351: Not Collective
353: Input Parameter:
354: . snes - SNES context
356: Output Parameter:
357: . iter - iteration number
359: Notes:
360: For example, during the computation of iteration 2 this would return 1.
362: This is useful for using lagged Jacobians (where one does not recompute the
363: Jacobian at each SNES iteration). For example, the code
364: .vb
365: SNESGetIterationNumber(snes,&it);
366: if (!(it % 2)) {
367: [compute Jacobian here]
368: }
369: .ve
370: can be used in your ComputeJacobian() function to cause the Jacobian to be
371: recomputed every second SNES iteration.
373: Level: intermediate
375: .keywords: SNES, nonlinear, get, iteration, number,
377: .seealso: SNESGetFunctionNorm(), SNESGetNumberLinearIterations()
378: @*/
379: PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt* iter)
380: {
384: *iter = snes->iter;
385: return(0);
386: }
390: /*@
391: SNESGetFunctionNorm - Gets the norm of the current function that was set
392: with SNESSSetFunction().
394: Collective on SNES
396: Input Parameter:
397: . snes - SNES context
399: Output Parameter:
400: . fnorm - 2-norm of function
402: Level: intermediate
404: .keywords: SNES, nonlinear, get, function, norm
406: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetNumberLinearIterations()
407: @*/
408: PetscErrorCode SNESGetFunctionNorm(SNES snes,PetscScalar *fnorm)
409: {
413: *fnorm = snes->norm;
414: return(0);
415: }
419: /*@
420: SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
421: attempted by the nonlinear solver.
423: Not Collective
425: Input Parameter:
426: . snes - SNES context
428: Output Parameter:
429: . nfails - number of unsuccessful steps attempted
431: Notes:
432: This counter is reset to zero for each successive call to SNESSolve().
434: Level: intermediate
436: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
437: @*/
438: PetscErrorCode SNESGetNumberUnsuccessfulSteps(SNES snes,PetscInt* nfails)
439: {
443: *nfails = snes->numFailures;
444: return(0);
445: }
449: /*@
450: SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps
451: attempted by the nonlinear solver before it gives up.
453: Not Collective
455: Input Parameters:
456: + snes - SNES context
457: - maxFails - maximum of unsuccessful steps
459: Level: intermediate
461: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
462: @*/
463: PetscErrorCode SNESSetMaximumUnsuccessfulSteps(SNES snes, PetscInt maxFails)
464: {
467: snes->maxFailures = maxFails;
468: return(0);
469: }
473: /*@
474: SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps
475: attempted by the nonlinear solver before it gives up.
477: Not Collective
479: Input Parameter:
480: . snes - SNES context
482: Output Parameter:
483: . maxFails - maximum of unsuccessful steps
485: Level: intermediate
487: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
488: @*/
489: PetscErrorCode SNESGetMaximumUnsuccessfulSteps(SNES snes, PetscInt *maxFails)
490: {
494: *maxFails = snes->maxFailures;
495: return(0);
496: }
500: /*@
501: SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
502: linear solvers.
504: Not Collective
506: Input Parameter:
507: . snes - SNES context
509: Output Parameter:
510: . nfails - number of failed solves
512: Notes:
513: This counter is reset to zero for each successive call to SNESSolve().
515: Level: intermediate
517: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
518: @*/
519: PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
520: {
524: *nfails = snes->numLinearSolveFailures;
525: return(0);
526: }
530: /*@
531: SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
532: allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE
534: Collective on SNES
536: Input Parameters:
537: + snes - SNES context
538: - maxFails - maximum allowed linear solve failures
540: Level: intermediate
542: Notes: By default this is 1; that is SNES returns on the first failed linear solve
544: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
546: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
547: @*/
548: PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
549: {
552: snes->maxLinearSolveFailures = maxFails;
553: return(0);
554: }
558: /*@
559: SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
560: are allowed before SNES terminates
562: Not Collective
564: Input Parameter:
565: . snes - SNES context
567: Output Parameter:
568: . maxFails - maximum of unsuccessful solves allowed
570: Level: intermediate
572: Notes: By default this is 1; that is SNES returns on the first failed linear solve
574: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
576: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
577: @*/
578: PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
579: {
583: *maxFails = snes->maxLinearSolveFailures;
584: return(0);
585: }
589: /*@
590: SNESGetNumberLinearIterations - Gets the total number of linear iterations
591: used by the nonlinear solver.
593: Not Collective
595: Input Parameter:
596: . snes - SNES context
598: Output Parameter:
599: . lits - number of linear iterations
601: Notes:
602: This counter is reset to zero for each successive call to SNESSolve().
604: Level: intermediate
606: .keywords: SNES, nonlinear, get, number, linear, iterations
608: .seealso: SNESGetIterationNumber(), SNESGetFunctionNorm()
609: @*/
610: PetscErrorCode SNESGetNumberLinearIterations(SNES snes,PetscInt* lits)
611: {
615: *lits = snes->linear_its;
616: return(0);
617: }
621: /*@
622: SNESGetKSP - Returns the KSP context for a SNES solver.
624: Not Collective, but if SNES object is parallel, then KSP object is parallel
626: Input Parameter:
627: . snes - the SNES context
629: Output Parameter:
630: . ksp - the KSP context
632: Notes:
633: The user can then directly manipulate the KSP context to set various
634: options, etc. Likewise, the user can then extract and manipulate the
635: PC contexts as well.
637: Level: beginner
639: .keywords: SNES, nonlinear, get, KSP, context
641: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
642: @*/
643: PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp)
644: {
648: *ksp = snes->ksp;
649: return(0);
650: }
654: /*@
655: SNESSetKSP - Sets a KSP context for the SNES object to use
657: Not Collective, but the SNES and KSP objects must live on the same MPI_Comm
659: Input Parameters:
660: + snes - the SNES context
661: - ksp - the KSP context
663: Notes:
664: The SNES object already has its KSP object, you can obtain with SNESGetKSP()
665: so this routine is rarely needed.
667: The KSP object that is already in the SNES object has its reference count
668: decreased by one.
670: Level: developer
672: .keywords: SNES, nonlinear, get, KSP, context
674: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
675: @*/
676: PetscErrorCode SNESSetKSP(SNES snes,KSP ksp)
677: {
684: if (ksp) {PetscObjectReference((PetscObject)ksp);}
685: if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
686: snes->ksp = ksp;
687: return(0);
688: }
692: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
693: {
695: return(0);
696: }
698: /* -----------------------------------------------------------*/
701: /*@
702: SNESCreate - Creates a nonlinear solver context.
704: Collective on MPI_Comm
706: Input Parameters:
707: . comm - MPI communicator
709: Output Parameter:
710: . outsnes - the new SNES context
712: Options Database Keys:
713: + -snes_mf - Activates default matrix-free Jacobian-vector products,
714: and no preconditioning matrix
715: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
716: products, and a user-provided preconditioning matrix
717: as set by SNESSetJacobian()
718: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
720: Level: beginner
722: .keywords: SNES, nonlinear, create, context
724: .seealso: SNESSolve(), SNESDestroy(), SNES
725: @*/
726: PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes)
727: {
728: PetscErrorCode ierr;
729: SNES snes;
730: SNES_KSP_EW_ConvCtx *kctx;
734: *outsnes = PETSC_NULL;
735: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
736: SNESInitializePackage(PETSC_NULL);
737: #endif
739: PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
740: snes->bops->publish = SNESPublish_Petsc;
741: snes->max_its = 50;
742: snes->max_funcs = 10000;
743: snes->norm = 0.0;
744: snes->rtol = 1.e-8;
745: snes->ttol = 0.0;
746: snes->abstol = 1.e-50;
747: snes->xtol = 1.e-8;
748: snes->deltatol = 1.e-12;
749: snes->nfuncs = 0;
750: snes->numFailures = 0;
751: snes->maxFailures = 1;
752: snes->linear_its = 0;
753: snes->numbermonitors = 0;
754: snes->data = 0;
755: snes->ops->view = 0;
756: snes->setupcalled = PETSC_FALSE;
757: snes->ksp_ewconv = PETSC_FALSE;
758: snes->vwork = 0;
759: snes->nwork = 0;
760: snes->conv_hist_len = 0;
761: snes->conv_hist_max = 0;
762: snes->conv_hist = PETSC_NULL;
763: snes->conv_hist_its = PETSC_NULL;
764: snes->conv_hist_reset = PETSC_TRUE;
765: snes->reason = SNES_CONVERGED_ITERATING;
767: snes->numLinearSolveFailures = 0;
768: snes->maxLinearSolveFailures = 1;
770: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
771: PetscNew(SNES_KSP_EW_ConvCtx,&kctx);
772: PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));
773: snes->kspconvctx = (void*)kctx;
774: kctx->version = 2;
775: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
776: this was too large for some test cases */
777: kctx->rtol_last = 0;
778: kctx->rtol_max = .9;
779: kctx->gamma = 1.0;
780: kctx->alpha2 = .5*(1.0 + sqrt(5.0));
781: kctx->alpha = kctx->alpha2;
782: kctx->threshold = .1;
783: kctx->lresid_last = 0;
784: kctx->norm_last = 0;
786: KSPCreate(comm,&snes->ksp);
787: PetscLogObjectParent(snes,snes->ksp);
789: *outsnes = snes;
790: PetscPublishAll(snes);
791: return(0);
792: }
796: /*@C
797: SNESSetFunction - Sets the function evaluation routine and function
798: vector for use by the SNES routines in solving systems of nonlinear
799: equations.
801: Collective on SNES
803: Input Parameters:
804: + snes - the SNES context
805: . func - function evaluation routine
806: . r - vector to store function value
807: - ctx - [optional] user-defined context for private data for the
808: function evaluation routine (may be PETSC_NULL)
810: Calling sequence of func:
811: $ func (SNES snes,Vec x,Vec f,void *ctx);
813: . f - function vector
814: - ctx - optional user-defined function context
816: Notes:
817: The Newton-like methods typically solve linear systems of the form
818: $ f'(x) x = -f(x),
819: where f'(x) denotes the Jacobian matrix and f(x) is the function.
821: Level: beginner
823: .keywords: SNES, nonlinear, set, function
825: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
826: @*/
827: PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
828: {
834: snes->ops->computefunction = func;
835: snes->vec_func = snes->vec_func_always = r;
836: snes->funP = ctx;
837: return(0);
838: }
840: /* --------------------------------------------------------------- */
843: /*@C
844: SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set
845: it assumes a zero right hand side.
847: Collective on SNES
849: Input Parameters:
850: + snes - the SNES context
851: - rhs - the right hand side vector or PETSC_NULL for a zero right hand side
853: Level: intermediate
855: .keywords: SNES, nonlinear, set, function, right hand side
857: .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
858: @*/
859: PetscErrorCode SNESSetRhs(SNES snes,Vec rhs)
860: {
865: if (rhs) {
868: PetscObjectReference((PetscObject)rhs);
869: }
870: if (snes->afine) {
871: VecDestroy(snes->afine);
872: }
873: snes->afine = rhs;
874: return(0);
875: }
879: /*@C
880: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
881: it assumes a zero right hand side.
883: Collective on SNES
885: Input Parameter:
886: . snes - the SNES context
888: Output Parameter:
889: . rhs - the right hand side vector or PETSC_NULL for a zero right hand side
891: Level: intermediate
893: .keywords: SNES, nonlinear, get, function, right hand side
895: .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
896: @*/
897: PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs)
898: {
902: *rhs = snes->afine;
903: return(0);
904: }
908: /*@
909: SNESComputeFunction - Calls the function that has been set with
910: SNESSetFunction().
912: Collective on SNES
914: Input Parameters:
915: + snes - the SNES context
916: - x - input vector
918: Output Parameter:
919: . y - function vector, as set by SNESSetFunction()
921: Notes:
922: SNESComputeFunction() is typically used within nonlinear solvers
923: implementations, so most users would not generally call this routine
924: themselves.
926: Level: developer
928: .keywords: SNES, nonlinear, compute, function
930: .seealso: SNESSetFunction(), SNESGetFunction()
931: @*/
932: PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y)
933: {
944: if (snes->ops->computefunction) {
945: PetscStackPush("SNES user function");
946: CHKMEMQ;
947: (*snes->ops->computefunction)(snes,x,y,snes->funP);
948: CHKMEMQ;
949: PetscStackPop;
950: if (PetscExceptionValue(ierr)) {
952: }
953:
954: } else if (snes->afine) {
955: MatMult(snes->jacobian, x, y);
956: } else {
957: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
958: }
959: if (snes->afine) {
960: VecAXPY(y,-1.0,snes->afine);
961: }
962: snes->nfuncs++;
964: return(0);
965: }
969: /*@
970: SNESComputeJacobian - Computes the Jacobian matrix that has been
971: set with SNESSetJacobian().
973: Collective on SNES and Mat
975: Input Parameters:
976: + snes - the SNES context
977: - x - input vector
979: Output Parameters:
980: + A - Jacobian matrix
981: . B - optional preconditioning matrix
982: - flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)
984: Notes:
985: Most users should not need to explicitly call this routine, as it
986: is used internally within the nonlinear solvers.
988: See KSPSetOperators() for important information about setting the
989: flag parameter.
991: Level: developer
993: .keywords: SNES, compute, Jacobian, matrix
995: .seealso: SNESSetJacobian(), KSPSetOperators(), MatStructure
996: @*/
997: PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
998: {
1006: if (!snes->ops->computejacobian) return(0);
1008: *flg = DIFFERENT_NONZERO_PATTERN;
1009: PetscStackPush("SNES user Jacobian function");
1010: CHKMEMQ;
1011: (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1012: CHKMEMQ;
1013: PetscStackPop;
1015: /* make sure user returned a correct Jacobian and preconditioner */
1018: return(0);
1019: }
1023: /*@C
1024: SNESSetJacobian - Sets the function to compute Jacobian as well as the
1025: location to store the matrix.
1027: Collective on SNES and Mat
1029: Input Parameters:
1030: + snes - the SNES context
1031: . A - Jacobian matrix
1032: . B - preconditioner matrix (usually same as the Jacobian)
1033: . func - Jacobian evaluation routine
1034: - ctx - [optional] user-defined context for private data for the
1035: Jacobian evaluation routine (may be PETSC_NULL)
1037: Calling sequence of func:
1038: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
1040: + x - input vector
1041: . A - Jacobian matrix
1042: . B - preconditioner matrix, usually the same as A
1043: . flag - flag indicating information about the preconditioner matrix
1044: structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1045: - ctx - [optional] user-defined Jacobian context
1047: Notes:
1048: See KSPSetOperators() for important information about setting the flag
1049: output parameter in the routine func(). Be sure to read this information!
1051: The routine func() takes Mat * as the matrix arguments rather than Mat.
1052: This allows the Jacobian evaluation routine to replace A and/or B with a
1053: completely new new matrix structure (not just different matrix elements)
1054: when appropriate, for instance, if the nonzero structure is changing
1055: throughout the global iterations.
1057: Level: beginner
1059: .keywords: SNES, nonlinear, set, Jacobian, matrix
1061: .seealso: KSPSetOperators(), SNESSetFunction(), MatSNESMFComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1062: @*/
1063: PetscErrorCode SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1064: {
1073: if (func) snes->ops->computejacobian = func;
1074: if (ctx) snes->jacP = ctx;
1075: if (A) {
1076: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1077: snes->jacobian = A;
1078: PetscObjectReference((PetscObject)A);
1079: }
1080: if (B) {
1081: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1082: snes->jacobian_pre = B;
1083: PetscObjectReference((PetscObject)B);
1084: }
1085: KSPSetOperators(snes->ksp,A,B,SAME_NONZERO_PATTERN);
1086: return(0);
1087: }
1091: /*@C
1092: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
1093: provided context for evaluating the Jacobian.
1095: Not Collective, but Mat object will be parallel if SNES object is
1097: Input Parameter:
1098: . snes - the nonlinear solver context
1100: Output Parameters:
1101: + A - location to stash Jacobian matrix (or PETSC_NULL)
1102: . B - location to stash preconditioner matrix (or PETSC_NULL)
1103: . func - location to put Jacobian function (or PETSC_NULL)
1104: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
1106: Level: advanced
1108: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1109: @*/
1110: PetscErrorCode SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1111: {
1114: if (A) *A = snes->jacobian;
1115: if (B) *B = snes->jacobian_pre;
1116: if (func) *func = snes->ops->computejacobian;
1117: if (ctx) *ctx = snes->jacP;
1118: return(0);
1119: }
1121: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1122: EXTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
1126: /*@
1127: SNESSetUp - Sets up the internal data structures for the later use
1128: of a nonlinear solver.
1130: Collective on SNES
1132: Input Parameters:
1133: . snes - the SNES context
1135: Notes:
1136: For basic use of the SNES solvers the user need not explicitly call
1137: SNESSetUp(), since these actions will automatically occur during
1138: the call to SNESSolve(). However, if one wishes to control this
1139: phase separately, SNESSetUp() should be called after SNESCreate()
1140: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1142: Level: advanced
1144: .keywords: SNES, nonlinear, setup
1146: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1147: @*/
1148: PetscErrorCode SNESSetUp(SNES snes)
1149: {
1151: PetscTruth flg, iseqtr;
1155: if (snes->setupcalled) return(0);
1157: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
1158: /*
1159: This version replaces the user provided Jacobian matrix with a
1160: matrix-free version but still employs the user-provided preconditioner matrix
1161: */
1162: if (flg) {
1163: Mat J;
1164: MatCreateSNESMF(snes,snes->vec_sol,&J);
1165: MatSNESMFSetFromOptions(J);
1166: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1167: SNESSetJacobian(snes,J,0,0,0);
1168: MatDestroy(J);
1169: }
1171: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1172: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
1173: if (flg) {
1174: Mat J;
1175: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1176: SNESSetJacobian(snes,J,0,0,0);
1177: MatDestroy(J);
1178: }
1179: #endif
1181: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
1182: /*
1183: This version replaces both the user-provided Jacobian and the user-
1184: provided preconditioner matrix with the default matrix free version.
1185: */
1186: if (flg) {
1187: Mat J;
1188: KSP ksp;
1189: PC pc;
1191: MatCreateSNESMF(snes,snes->vec_sol,&J);
1192: MatSNESMFSetFromOptions(J);
1193: PetscInfo(snes,"Setting default matrix-free operator and preconditioner routines;\nThat is no preconditioner is being used.\n");
1194: SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);
1195: MatDestroy(J);
1197: /* force no preconditioner */
1198: SNESGetKSP(snes,&ksp);
1199: KSPGetPC(ksp,&pc);
1200: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1201: if (!flg) {
1202: PCSetType(pc,PCNONE);
1203: }
1204: }
1206: if (!snes->vec_func && !snes->afine) {
1207: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1208: }
1209: if (!snes->ops->computefunction && !snes->afine) {
1210: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1211: }
1212: if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1213: if (snes->vec_func == snes->vec_sol) {
1214: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1215: }
1217: /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
1218: PetscTypeCompare((PetscObject)snes,SNESTR,&iseqtr);
1219: if (snes->ksp_ewconv && !iseqtr) {
1220: KSP ksp;
1221: SNESGetKSP(snes,&ksp);
1222: KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,snes);
1223: }
1225: if (snes->ops->setup) {(*snes->ops->setup)(snes);}
1226: snes->setupcalled = PETSC_TRUE;
1227: return(0);
1228: }
1232: /*@
1233: SNESDestroy - Destroys the nonlinear solver context that was created
1234: with SNESCreate().
1236: Collective on SNES
1238: Input Parameter:
1239: . snes - the SNES context
1241: Level: beginner
1243: .keywords: SNES, nonlinear, destroy
1245: .seealso: SNESCreate(), SNESSolve()
1246: @*/
1247: PetscErrorCode SNESDestroy(SNES snes)
1248: {
1253: if (--snes->refct > 0) return(0);
1255: /* if memory was published with AMS then destroy it */
1256: PetscObjectDepublish(snes);
1258: if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1259: PetscFree(snes->kspconvctx);
1260: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1261: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1262: if (snes->afine) {VecDestroy(snes->afine);}
1263: KSPDestroy(snes->ksp);
1264: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1265: SNESClearMonitor(snes);
1266: PetscHeaderDestroy(snes);
1267: return(0);
1268: }
1270: /* ----------- Routines to set solver parameters ---------- */
1274: /*@
1275: SNESSetTolerances - Sets various parameters used in convergence tests.
1277: Collective on SNES
1279: Input Parameters:
1280: + snes - the SNES context
1281: . abstol - absolute convergence tolerance
1282: . rtol - relative convergence tolerance
1283: . stol - convergence tolerance in terms of the norm
1284: of the change in the solution between steps
1285: . maxit - maximum number of iterations
1286: - maxf - maximum number of function evaluations
1288: Options Database Keys:
1289: + -snes_atol <abstol> - Sets abstol
1290: . -snes_rtol <rtol> - Sets rtol
1291: . -snes_stol <stol> - Sets stol
1292: . -snes_max_it <maxit> - Sets maxit
1293: - -snes_max_funcs <maxf> - Sets maxf
1295: Notes:
1296: The default maximum number of iterations is 50.
1297: The default maximum number of function evaluations is 1000.
1299: Level: intermediate
1301: .keywords: SNES, nonlinear, set, convergence, tolerances
1303: .seealso: SNESSetTrustRegionTolerance()
1304: @*/
1305: PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1306: {
1309: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1310: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1311: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1312: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1313: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1314: return(0);
1315: }
1319: /*@
1320: SNESGetTolerances - Gets various parameters used in convergence tests.
1322: Not Collective
1324: Input Parameters:
1325: + snes - the SNES context
1326: . abstol - absolute convergence tolerance
1327: . rtol - relative convergence tolerance
1328: . stol - convergence tolerance in terms of the norm
1329: of the change in the solution between steps
1330: . maxit - maximum number of iterations
1331: - maxf - maximum number of function evaluations
1333: Notes:
1334: The user can specify PETSC_NULL for any parameter that is not needed.
1336: Level: intermediate
1338: .keywords: SNES, nonlinear, get, convergence, tolerances
1340: .seealso: SNESSetTolerances()
1341: @*/
1342: PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *abstol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1343: {
1346: if (abstol) *abstol = snes->abstol;
1347: if (rtol) *rtol = snes->rtol;
1348: if (stol) *stol = snes->xtol;
1349: if (maxit) *maxit = snes->max_its;
1350: if (maxf) *maxf = snes->max_funcs;
1351: return(0);
1352: }
1356: /*@
1357: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1359: Collective on SNES
1361: Input Parameters:
1362: + snes - the SNES context
1363: - tol - tolerance
1364:
1365: Options Database Key:
1366: . -snes_trtol <tol> - Sets tol
1368: Level: intermediate
1370: .keywords: SNES, nonlinear, set, trust region, tolerance
1372: .seealso: SNESSetTolerances()
1373: @*/
1374: PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1375: {
1378: snes->deltatol = tol;
1379: return(0);
1380: }
1382: /*
1383: Duplicate the lg monitors for SNES from KSP; for some reason with
1384: dynamic libraries things don't work under Sun4 if we just use
1385: macros instead of functions
1386: */
1389: PetscErrorCode SNESLGMonitor(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1390: {
1395: KSPLGMonitor((KSP)snes,it,norm,ctx);
1396: return(0);
1397: }
1401: PetscErrorCode SNESLGMonitorCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1402: {
1406: KSPLGMonitorCreate(host,label,x,y,m,n,draw);
1407: return(0);
1408: }
1412: PetscErrorCode SNESLGMonitorDestroy(PetscDrawLG draw)
1413: {
1417: KSPLGMonitorDestroy(draw);
1418: return(0);
1419: }
1421: /* ------------ Routines to set performance monitoring options ----------- */
1425: /*@C
1426: SNESSetMonitor - Sets an ADDITIONAL function that is to be used at every
1427: iteration of the nonlinear solver to display the iteration's
1428: progress.
1430: Collective on SNES
1432: Input Parameters:
1433: + snes - the SNES context
1434: . func - monitoring routine
1435: . mctx - [optional] user-defined context for private data for the
1436: monitor routine (use PETSC_NULL if no context is desired)
1437: - monitordestroy - [optional] routine that frees monitor context
1438: (may be PETSC_NULL)
1440: Calling sequence of func:
1441: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1443: + snes - the SNES context
1444: . its - iteration number
1445: . norm - 2-norm function value (may be estimated)
1446: - mctx - [optional] monitoring context
1448: Options Database Keys:
1449: + -snes_monitor - sets SNESDefaultMonitor()
1450: . -snes_xmonitor - sets line graph monitor,
1451: uses SNESLGMonitorCreate()
1452: _ -snes_cancelmonitors - cancels all monitors that have
1453: been hardwired into a code by
1454: calls to SNESSetMonitor(), but
1455: does not cancel those set via
1456: the options database.
1458: Notes:
1459: Several different monitoring routines may be set by calling
1460: SNESSetMonitor() multiple times; all will be called in the
1461: order in which they were set.
1463: Level: intermediate
1465: .keywords: SNES, nonlinear, set, monitor
1467: .seealso: SNESDefaultMonitor(), SNESClearMonitor()
1468: @*/
1469: PetscErrorCode SNESSetMonitor(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1470: {
1473: if (snes->numbermonitors >= MAXSNESMONITORS) {
1474: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1475: }
1476: snes->monitor[snes->numbermonitors] = func;
1477: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1478: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1479: return(0);
1480: }
1484: /*@C
1485: SNESClearMonitor - Clears all the monitor functions for a SNES object.
1487: Collective on SNES
1489: Input Parameters:
1490: . snes - the SNES context
1492: Options Database Key:
1493: . -snes_cancelmonitors - cancels all monitors that have been hardwired
1494: into a code by calls to SNESSetMonitor(), but does not cancel those
1495: set via the options database
1497: Notes:
1498: There is no way to clear one specific monitor from a SNES object.
1500: Level: intermediate
1502: .keywords: SNES, nonlinear, set, monitor
1504: .seealso: SNESDefaultMonitor(), SNESSetMonitor()
1505: @*/
1506: PetscErrorCode SNESClearMonitor(SNES snes)
1507: {
1509: PetscInt i;
1513: for (i=0; i<snes->numbermonitors; i++) {
1514: if (snes->monitordestroy[i]) {
1515: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1516: }
1517: }
1518: snes->numbermonitors = 0;
1519: return(0);
1520: }
1524: /*@C
1525: SNESSetConvergenceTest - Sets the function that is to be used
1526: to test for convergence of the nonlinear iterative solution.
1528: Collective on SNES
1530: Input Parameters:
1531: + snes - the SNES context
1532: . func - routine to test for convergence
1533: - cctx - [optional] context for private data for the convergence routine
1534: (may be PETSC_NULL)
1536: Calling sequence of func:
1537: $ PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1539: + snes - the SNES context
1540: . it - current iteration (0 is the first and is before any Newton step)
1541: . cctx - [optional] convergence context
1542: . reason - reason for convergence/divergence
1543: . xnorm - 2-norm of current iterate
1544: . gnorm - 2-norm of current step
1545: - f - 2-norm of function
1547: Level: advanced
1549: .keywords: SNES, nonlinear, set, convergence, test
1551: .seealso: SNESConverged_LS(), SNESConverged_TR()
1552: @*/
1553: PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1554: {
1557: (snes)->ops->converged = func;
1558: (snes)->cnvP = cctx;
1559: return(0);
1560: }
1564: /*@
1565: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1567: Not Collective
1569: Input Parameter:
1570: . snes - the SNES context
1572: Output Parameter:
1573: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1574: manual pages for the individual convergence tests for complete lists
1576: Level: intermediate
1578: Notes: Can only be called after the call the SNESSolve() is complete.
1580: .keywords: SNES, nonlinear, set, convergence, test
1582: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1583: @*/
1584: PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1585: {
1589: *reason = snes->reason;
1590: return(0);
1591: }
1595: /*@
1596: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1598: Collective on SNES
1600: Input Parameters:
1601: + snes - iterative context obtained from SNESCreate()
1602: . a - array to hold history
1603: . its - integer array holds the number of linear iterations for each solve.
1604: . na - size of a and its
1605: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1606: else it continues storing new values for new nonlinear solves after the old ones
1608: Notes:
1609: If set, this array will contain the function norms computed
1610: at each step.
1612: This routine is useful, e.g., when running a code for purposes
1613: of accurate performance monitoring, when no I/O should be done
1614: during the section of code that is being timed.
1616: Level: intermediate
1618: .keywords: SNES, set, convergence, history
1620: .seealso: SNESGetConvergenceHistory()
1622: @*/
1623: PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt *its,PetscInt na,PetscTruth reset)
1624: {
1628: snes->conv_hist = a;
1629: snes->conv_hist_its = its;
1630: snes->conv_hist_max = na;
1631: snes->conv_hist_reset = reset;
1632: return(0);
1633: }
1637: /*@C
1638: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1640: Collective on SNES
1642: Input Parameter:
1643: . snes - iterative context obtained from SNESCreate()
1645: Output Parameters:
1646: . a - array to hold history
1647: . its - integer array holds the number of linear iterations (or
1648: negative if not converged) for each solve.
1649: - na - size of a and its
1651: Notes:
1652: The calling sequence for this routine in Fortran is
1653: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1655: This routine is useful, e.g., when running a code for purposes
1656: of accurate performance monitoring, when no I/O should be done
1657: during the section of code that is being timed.
1659: Level: intermediate
1661: .keywords: SNES, get, convergence, history
1663: .seealso: SNESSetConvergencHistory()
1665: @*/
1666: PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1667: {
1670: if (a) *a = snes->conv_hist;
1671: if (its) *its = snes->conv_hist_its;
1672: if (na) *na = snes->conv_hist_len;
1673: return(0);
1674: }
1678: /*@C
1679: SNESSetUpdate - Sets the general-purpose update function called
1680: at the beginning o every iteration of the nonlinear solve. Specifically
1681: it is called just before the Jacobian is "evaluated".
1683: Collective on SNES
1685: Input Parameters:
1686: . snes - The nonlinear solver context
1687: . func - The function
1689: Calling sequence of func:
1690: . func (SNES snes, PetscInt step);
1692: . step - The current step of the iteration
1694: Level: intermediate
1696: .keywords: SNES, update
1698: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1699: @*/
1700: PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1701: {
1704: snes->ops->update = func;
1705: return(0);
1706: }
1710: /*@
1711: SNESDefaultUpdate - The default update function which does nothing.
1713: Not collective
1715: Input Parameters:
1716: . snes - The nonlinear solver context
1717: . step - The current step of the iteration
1719: Level: intermediate
1721: .keywords: SNES, update
1722: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultSolutionBC()
1723: @*/
1724: PetscErrorCode SNESDefaultUpdate(SNES snes, PetscInt step)
1725: {
1727: return(0);
1728: }
1732: /*
1733: SNESScaleStep_Private - Scales a step so that its length is less than the
1734: positive parameter delta.
1736: Input Parameters:
1737: + snes - the SNES context
1738: . y - approximate solution of linear system
1739: . fnorm - 2-norm of current function
1740: - delta - trust region size
1742: Output Parameters:
1743: + gpnorm - predicted function norm at the new point, assuming local
1744: linearization. The value is zero if the step lies within the trust
1745: region, and exceeds zero otherwise.
1746: - ynorm - 2-norm of the step
1748: Note:
1749: For non-trust region methods such as SNESLS, the parameter delta
1750: is set to be the maximum allowable step size.
1752: .keywords: SNES, nonlinear, scale, step
1753: */
1754: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1755: {
1756: PetscReal nrm;
1757: PetscScalar cnorm;
1765: VecNorm(y,NORM_2,&nrm);
1766: if (nrm > *delta) {
1767: nrm = *delta/nrm;
1768: *gpnorm = (1.0 - nrm)*(*fnorm);
1769: cnorm = nrm;
1770: VecScale(y,cnorm);
1771: *ynorm = *delta;
1772: } else {
1773: *gpnorm = 0.0;
1774: *ynorm = nrm;
1775: }
1776: return(0);
1777: }
1781: /*@C
1782: SNESSolve - Solves a nonlinear system F(x) = b.
1783: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
1785: Collective on SNES
1787: Input Parameters:
1788: + snes - the SNES context
1789: . b - the constant part of the equation, or PETSC_NULL to use zero.
1790: - x - the solution vector, or PETSC_NULL if it was set with SNESSetSolution()
1792: Notes:
1793: The user should initialize the vector,x, with the initial guess
1794: for the nonlinear solve prior to calling SNESSolve. In particular,
1795: to employ an initial guess of zero, the user should explicitly set
1796: this vector to zero by calling VecSet().
1798: Level: beginner
1800: .keywords: SNES, nonlinear, solve
1802: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetRhs(), SNESSetSolution()
1803: @*/
1804: PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x)
1805: {
1807: PetscTruth flg;
1808: char filename[PETSC_MAX_PATH_LEN];
1809: PetscViewer viewer;
1813: if (!snes->ops->solve) SETERRQ(PETSC_ERR_ORDER,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1815: if (b) {
1816: SNESSetRhs(snes, b);
1817: if (!snes->vec_func) {
1818: Vec r;
1820: VecDuplicate(b, &r);
1821: SNESSetFunction(snes, r, PETSC_NULL, PETSC_NULL);
1822: }
1823: }
1824: if (x) {
1827: } else {
1828: SNESGetSolution(snes, &x);
1829: if (!x) {
1830: VecDuplicate(snes->vec_func_always, &x);
1831: }
1832: }
1833: snes->vec_sol = snes->vec_sol_always = x;
1834: if (!snes->setupcalled) {
1835: SNESSetUp(snes);
1836: }
1837: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1839: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1841: PetscExceptionTry1((*(snes)->ops->solve)(snes),PETSC_ERR_ARG_DOMAIN);
1842: if (PetscExceptionValue(ierr)) {
1843: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
1845: } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) {
1846: /* translate exception into SNES not converged reason */
1847: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
1848: 0;
1849: }
1850:
1853: PetscOptionsGetString(snes->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
1854: if (flg && !PetscPreLoadingOn) {
1855: PetscViewerASCIIOpen(snes->comm,filename,&viewer);
1856: SNESView(snes,viewer);
1857: PetscViewerDestroy(viewer);
1858: }
1860: PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);
1861: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1862: if (snes->printreason) {
1863: if (snes->reason > 0) {
1864: PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1865: } else {
1866: PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1867: }
1868: }
1870: return(0);
1871: }
1873: /* --------- Internal routines for SNES Package --------- */
1877: /*@C
1878: SNESSetType - Sets the method for the nonlinear solver.
1880: Collective on SNES
1882: Input Parameters:
1883: + snes - the SNES context
1884: - type - a known method
1886: Options Database Key:
1887: . -snes_type <type> - Sets the method; use -help for a list
1888: of available methods (for instance, ls or tr)
1890: Notes:
1891: See "petsc/include/petscsnes.h" for available methods (for instance)
1892: + SNESLS - Newton's method with line search
1893: (systems of nonlinear equations)
1894: . SNESTR - Newton's method with trust region
1895: (systems of nonlinear equations)
1897: Normally, it is best to use the SNESSetFromOptions() command and then
1898: set the SNES solver type from the options database rather than by using
1899: this routine. Using the options database provides the user with
1900: maximum flexibility in evaluating the many nonlinear solvers.
1901: The SNESSetType() routine is provided for those situations where it
1902: is necessary to set the nonlinear solver independently of the command
1903: line or options database. This might be the case, for example, when
1904: the choice of solver changes during the execution of the program,
1905: and the user's application is taking responsibility for choosing the
1906: appropriate method.
1908: Level: intermediate
1910: .keywords: SNES, set, type
1912: .seealso: SNESType, SNESCreate()
1914: @*/
1915: PetscErrorCode SNESSetType(SNES snes,SNESType type)
1916: {
1917: PetscErrorCode ierr,(*r)(SNES);
1918: PetscTruth match;
1924: PetscTypeCompare((PetscObject)snes,type,&match);
1925: if (match) return(0);
1927: if (snes->setupcalled) {
1928: snes->setupcalled = PETSC_FALSE;
1929: (*(snes)->ops->destroy)(snes);
1930: snes->data = 0;
1931: }
1933: /* Get the function pointers for the iterative method requested */
1934: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
1935: PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);
1936: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1937: PetscFree(snes->data);
1938: snes->data = 0;
1939: (*r)(snes);
1940: PetscObjectChangeTypeName((PetscObject)snes,type);
1941: return(0);
1942: }
1945: /* --------------------------------------------------------------------- */
1948: /*@
1949: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1950: registered by SNESRegisterDynamic().
1952: Not Collective
1954: Level: advanced
1956: .keywords: SNES, nonlinear, register, destroy
1958: .seealso: SNESRegisterAll(), SNESRegisterAll()
1959: @*/
1960: PetscErrorCode SNESRegisterDestroy(void)
1961: {
1965: if (SNESList) {
1966: PetscFListDestroy(&SNESList);
1967: SNESList = 0;
1968: }
1969: SNESRegisterAllCalled = PETSC_FALSE;
1970: return(0);
1971: }
1975: /*@C
1976: SNESGetType - Gets the SNES method type and name (as a string).
1978: Not Collective
1980: Input Parameter:
1981: . snes - nonlinear solver context
1983: Output Parameter:
1984: . type - SNES method (a character string)
1986: Level: intermediate
1988: .keywords: SNES, nonlinear, get, type, name
1989: @*/
1990: PetscErrorCode SNESGetType(SNES snes,SNESType *type)
1991: {
1995: *type = snes->type_name;
1996: return(0);
1997: }
2001: /*@
2002: SNESGetSolution - Returns the vector where the approximate solution is
2003: stored.
2005: Not Collective, but Vec is parallel if SNES is parallel
2007: Input Parameter:
2008: . snes - the SNES context
2010: Output Parameter:
2011: . x - the solution
2013: Level: intermediate
2015: .keywords: SNES, nonlinear, get, solution
2017: .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
2018: @*/
2019: PetscErrorCode SNESGetSolution(SNES snes,Vec *x)
2020: {
2024: *x = snes->vec_sol_always;
2025: return(0);
2026: }
2030: /*@
2031: SNESSetSolution - Sets the vector where the approximate solution is stored.
2033: Not Collective, but Vec is parallel if SNES is parallel
2035: Input Parameters:
2036: + snes - the SNES context
2037: - x - the solution
2039: Output Parameter:
2041: Level: intermediate
2043: Notes: this is not normally used, rather one simply calls SNESSolve() with
2044: the appropriate solution vector.
2046: .keywords: SNES, nonlinear, set, solution
2048: .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
2049: @*/
2050: PetscErrorCode SNESSetSolution(SNES snes,Vec x)
2051: {
2056: snes->vec_sol_always = x;
2057: return(0);
2058: }
2062: /*@
2063: SNESGetSolutionUpdate - Returns the vector where the solution update is
2064: stored.
2066: Not Collective, but Vec is parallel if SNES is parallel
2068: Input Parameter:
2069: . snes - the SNES context
2071: Output Parameter:
2072: . x - the solution update
2074: Level: advanced
2076: .keywords: SNES, nonlinear, get, solution, update
2078: .seealso: SNESGetSolution(), SNESGetFunction
2079: @*/
2080: PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x)
2081: {
2085: *x = snes->vec_sol_update_always;
2086: return(0);
2087: }
2091: /*@C
2092: SNESGetFunction - Returns the vector where the function is stored.
2094: Not Collective, but Vec is parallel if SNES is parallel
2096: Input Parameter:
2097: . snes - the SNES context
2099: Output Parameter:
2100: + r - the function (or PETSC_NULL)
2101: . func - the function (or PETSC_NULL)
2102: - ctx - the function context (or PETSC_NULL)
2104: Level: advanced
2106: .keywords: SNES, nonlinear, get, function
2108: .seealso: SNESSetFunction(), SNESGetSolution()
2109: @*/
2110: PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2111: {
2114: if (r) *r = snes->vec_func_always;
2115: if (func) *func = snes->ops->computefunction;
2116: if (ctx) *ctx = snes->funP;
2117: return(0);
2118: }
2122: /*@C
2123: SNESSetOptionsPrefix - Sets the prefix used for searching for all
2124: SNES options in the database.
2126: Collective on SNES
2128: Input Parameter:
2129: + snes - the SNES context
2130: - prefix - the prefix to prepend to all option names
2132: Notes:
2133: A hyphen (-) must NOT be given at the beginning of the prefix name.
2134: The first character of all runtime options is AUTOMATICALLY the hyphen.
2136: Level: advanced
2138: .keywords: SNES, set, options, prefix, database
2140: .seealso: SNESSetFromOptions()
2141: @*/
2142: PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[])
2143: {
2148: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2149: KSPSetOptionsPrefix(snes->ksp,prefix);
2150: return(0);
2151: }
2155: /*@C
2156: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2157: SNES options in the database.
2159: Collective on SNES
2161: Input Parameters:
2162: + snes - the SNES context
2163: - prefix - the prefix to prepend to all option names
2165: Notes:
2166: A hyphen (-) must NOT be given at the beginning of the prefix name.
2167: The first character of all runtime options is AUTOMATICALLY the hyphen.
2169: Level: advanced
2171: .keywords: SNES, append, options, prefix, database
2173: .seealso: SNESGetOptionsPrefix()
2174: @*/
2175: PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2176: {
2178:
2181: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2182: KSPAppendOptionsPrefix(snes->ksp,prefix);
2183: return(0);
2184: }
2188: /*@C
2189: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2190: SNES options in the database.
2192: Not Collective
2194: Input Parameter:
2195: . snes - the SNES context
2197: Output Parameter:
2198: . prefix - pointer to the prefix string used
2200: Notes: On the fortran side, the user should pass in a string 'prifix' of
2201: sufficient length to hold the prefix.
2203: Level: advanced
2205: .keywords: SNES, get, options, prefix, database
2207: .seealso: SNESAppendOptionsPrefix()
2208: @*/
2209: PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2210: {
2215: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2216: return(0);
2217: }
2222: /*@C
2223: SNESRegister - See SNESRegisterDynamic()
2225: Level: advanced
2226: @*/
2227: PetscErrorCode SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2228: {
2229: char fullname[PETSC_MAX_PATH_LEN];
2233: PetscFListConcat(path,name,fullname);
2234: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2235: return(0);
2236: }
2240: PetscErrorCode SNESTestLocalMin(SNES snes)
2241: {
2243: PetscInt N,i,j;
2244: Vec u,uh,fh;
2245: PetscScalar value;
2246: PetscReal norm;
2249: SNESGetSolution(snes,&u);
2250: VecDuplicate(u,&uh);
2251: VecDuplicate(u,&fh);
2253: /* currently only works for sequential */
2254: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2255: VecGetSize(u,&N);
2256: for (i=0; i<N; i++) {
2257: VecCopy(u,uh);
2258: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2259: for (j=-10; j<11; j++) {
2260: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2261: VecSetValue(uh,i,value,ADD_VALUES);
2262: SNESComputeFunction(snes,uh,fh);
2263: VecNorm(fh,NORM_2,&norm);
2264: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2265: value = -value;
2266: VecSetValue(uh,i,value,ADD_VALUES);
2267: }
2268: }
2269: VecDestroy(uh);
2270: VecDestroy(fh);
2271: return(0);
2272: }