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 PETSCSNES_DLLEXPORT 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 PETSCSNES_DLLEXPORT 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->view) {
72: PetscViewerASCIIPushTab(viewer);
73: (*snes->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 PETSCSNES_DLLEXPORT 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 PETSCSNES_DLLEXPORT 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 or 2","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->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->setfromoptions) {
280: (*snes->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 PETSCSNES_DLLEXPORT 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 PETSCSNES_DLLEXPORT 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
376: @*/
377: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter)
378: {
382: *iter = snes->iter;
383: return(0);
384: }
388: /*@
389: SNESGetFunctionNorm - Gets the norm of the current function that was set
390: with SNESSSetFunction().
392: Collective on SNES
394: Input Parameter:
395: . snes - SNES context
397: Output Parameter:
398: . fnorm - 2-norm of function
400: Level: intermediate
402: .keywords: SNES, nonlinear, get, function, norm
404: .seealso: SNESGetFunction()
405: @*/
406: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscScalar *fnorm)
407: {
411: *fnorm = snes->norm;
412: return(0);
413: }
417: /*@
418: SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
419: attempted by the nonlinear solver.
421: Not Collective
423: Input Parameter:
424: . snes - SNES context
426: Output Parameter:
427: . nfails - number of unsuccessful steps attempted
429: Notes:
430: This counter is reset to zero for each successive call to SNESSolve().
432: Level: intermediate
434: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
435: @*/
436: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberUnsuccessfulSteps(SNES snes,PetscInt* nfails)
437: {
441: *nfails = snes->numFailures;
442: return(0);
443: }
447: /*@
448: SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps
449: attempted by the nonlinear solver before it gives up.
451: Not Collective
453: Input Parameters:
454: + snes - SNES context
455: - maxFails - maximum of unsuccessful steps
457: Level: intermediate
459: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
460: @*/
461: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaximumUnsuccessfulSteps(SNES snes, PetscInt maxFails)
462: {
465: snes->maxFailures = maxFails;
466: return(0);
467: }
471: /*@
472: SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps
473: attempted by the nonlinear solver before it gives up.
475: Not Collective
477: Input Parameter:
478: . snes - SNES context
480: Output Parameter:
481: . maxFails - maximum of unsuccessful steps
483: Level: intermediate
485: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
486: @*/
487: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaximumUnsuccessfulSteps(SNES snes, PetscInt *maxFails)
488: {
492: *maxFails = snes->maxFailures;
493: return(0);
494: }
498: /*@
499: SNESGetNumberLinearIterations - Gets the total number of linear iterations
500: used by the nonlinear solver.
502: Not Collective
504: Input Parameter:
505: . snes - SNES context
507: Output Parameter:
508: . lits - number of linear iterations
510: Notes:
511: This counter is reset to zero for each successive call to SNESSolve().
513: Level: intermediate
515: .keywords: SNES, nonlinear, get, number, linear, iterations
516: @*/
517: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberLinearIterations(SNES snes,PetscInt* lits)
518: {
522: *lits = snes->linear_its;
523: return(0);
524: }
528: /*@
529: SNESGetKSP - Returns the KSP context for a SNES solver.
531: Not Collective, but if SNES object is parallel, then KSP object is parallel
533: Input Parameter:
534: . snes - the SNES context
536: Output Parameter:
537: . ksp - the KSP context
539: Notes:
540: The user can then directly manipulate the KSP context to set various
541: options, etc. Likewise, the user can then extract and manipulate the
542: KSP and PC contexts as well.
544: Level: beginner
546: .keywords: SNES, nonlinear, get, KSP, context
548: .seealso: KSPGetPC()
549: @*/
550: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp)
551: {
555: *ksp = snes->ksp;
556: return(0);
557: }
561: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
562: {
564: return(0);
565: }
567: /* -----------------------------------------------------------*/
570: /*@
571: SNESCreate - Creates a nonlinear solver context.
573: Collective on MPI_Comm
575: Input Parameters:
576: + comm - MPI communicator
578: Output Parameter:
579: . outsnes - the new SNES context
581: Options Database Keys:
582: + -snes_mf - Activates default matrix-free Jacobian-vector products,
583: and no preconditioning matrix
584: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
585: products, and a user-provided preconditioning matrix
586: as set by SNESSetJacobian()
587: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
589: Level: beginner
591: .keywords: SNES, nonlinear, create, context
593: .seealso: SNESSolve(), SNESDestroy(), SNES
594: @*/
595: PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes)
596: {
597: PetscErrorCode ierr;
598: SNES snes;
599: SNES_KSP_EW_ConvCtx *kctx;
603: *outsnes = PETSC_NULL;
604: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
605: SNESInitializePackage(PETSC_NULL);
606: #endif
608: PetscHeaderCreate(snes,_p_SNES,PetscInt,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
609: snes->bops->publish = SNESPublish_Petsc;
610: snes->max_its = 50;
611: snes->max_funcs = 10000;
612: snes->norm = 0.0;
613: snes->rtol = 1.e-8;
614: snes->ttol = 0.0;
615: snes->abstol = 1.e-50;
616: snes->xtol = 1.e-8;
617: snes->deltatol = 1.e-12;
618: snes->nfuncs = 0;
619: snes->numFailures = 0;
620: snes->maxFailures = 1;
621: snes->linear_its = 0;
622: snes->numbermonitors = 0;
623: snes->data = 0;
624: snes->view = 0;
625: snes->setupcalled = PETSC_FALSE;
626: snes->ksp_ewconv = PETSC_FALSE;
627: snes->vwork = 0;
628: snes->nwork = 0;
629: snes->conv_hist_len = 0;
630: snes->conv_hist_max = 0;
631: snes->conv_hist = PETSC_NULL;
632: snes->conv_hist_its = PETSC_NULL;
633: snes->conv_hist_reset = PETSC_TRUE;
634: snes->reason = SNES_CONVERGED_ITERATING;
636: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
637: PetscNew(SNES_KSP_EW_ConvCtx,&kctx);
638: PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));
639: snes->kspconvctx = (void*)kctx;
640: kctx->version = 2;
641: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
642: this was too large for some test cases */
643: kctx->rtol_last = 0;
644: kctx->rtol_max = .9;
645: kctx->gamma = 1.0;
646: kctx->alpha2 = .5*(1.0 + sqrt(5.0));
647: kctx->alpha = kctx->alpha2;
648: kctx->threshold = .1;
649: kctx->lresid_last = 0;
650: kctx->norm_last = 0;
652: KSPCreate(comm,&snes->ksp);
653: PetscLogObjectParent(snes,snes->ksp);
655: *outsnes = snes;
656: PetscPublishAll(snes);
657: return(0);
658: }
662: /*@C
663: SNESSetFunction - Sets the function evaluation routine and function
664: vector for use by the SNES routines in solving systems of nonlinear
665: equations.
667: Collective on SNES
669: Input Parameters:
670: + snes - the SNES context
671: . func - function evaluation routine
672: . r - vector to store function value
673: - ctx - [optional] user-defined context for private data for the
674: function evaluation routine (may be PETSC_NULL)
676: Calling sequence of func:
677: $ func (SNES snes,Vec x,Vec f,void *ctx);
679: . f - function vector
680: - ctx - optional user-defined function context
682: Notes:
683: The Newton-like methods typically solve linear systems of the form
684: $ f'(x) x = -f(x),
685: where f'(x) denotes the Jacobian matrix and f(x) is the function.
687: Level: beginner
689: .keywords: SNES, nonlinear, set, function
691: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
692: @*/
693: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
694: {
700: snes->computefunction = func;
701: snes->vec_func = snes->vec_func_always = r;
702: snes->funP = ctx;
703: return(0);
704: }
706: /* --------------------------------------------------------------- */
709: /*@C
710: SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set
711: it assumes a zero right hand side.
713: Collective on SNES
715: Input Parameters:
716: + snes - the SNES context
717: - rhs - the right hand side vector or PETSC_NULL for a zero right hand side
719: Level: intermediate
721: .keywords: SNES, nonlinear, set, function, right hand side
723: .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
724: @*/
725: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRhs(SNES snes,Vec rhs)
726: {
731: if (rhs) {
734: PetscObjectReference((PetscObject)rhs);
735: }
736: if (snes->afine) {
737: VecDestroy(snes->afine);
738: }
739: snes->afine = rhs;
740: return(0);
741: }
745: /*@C
746: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
747: it assumes a zero right hand side.
749: Collective on SNES
751: Input Parameter:
752: . snes - the SNES context
754: Output Parameter:
755: . rhs - the right hand side vector or PETSC_NULL for a zero right hand side
757: Level: intermediate
759: .keywords: SNES, nonlinear, get, function, right hand side
761: .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
762: @*/
763: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs)
764: {
768: *rhs = snes->afine;
769: return(0);
770: }
774: /*@
775: SNESComputeFunction - Calls the function that has been set with
776: SNESSetFunction().
778: Collective on SNES
780: Input Parameters:
781: + snes - the SNES context
782: - x - input vector
784: Output Parameter:
785: . y - function vector, as set by SNESSetFunction()
787: Notes:
788: SNESComputeFunction() is typically used within nonlinear solvers
789: implementations, so most users would not generally call this routine
790: themselves.
792: Level: developer
794: .keywords: SNES, nonlinear, compute, function
796: .seealso: SNESSetFunction(), SNESGetFunction()
797: @*/
798: PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y)
799: {
809: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
810: if (snes->computefunction) {
811: PetscStackPush("SNES user function");
812: CHKMEMQ;
813: (*snes->computefunction)(snes,x,y,snes->funP);
814: CHKMEMQ;
815: PetscStackPop;
816: if (PetscExceptionValue(ierr)) {
817: PetscErrorCode pPetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
818: }
819:
820: } else if (snes->afine) {
821: MatMult(snes->jacobian, x, y);
822: } else {
823: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
824: }
825: if (snes->afine) {
826: VecAXPY(y,-1.0,snes->afine);
827: }
828: snes->nfuncs++;
829: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
830: return(0);
831: }
835: /*@
836: SNESComputeJacobian - Computes the Jacobian matrix that has been
837: set with SNESSetJacobian().
839: Collective on SNES and Mat
841: Input Parameters:
842: + snes - the SNES context
843: - x - input vector
845: Output Parameters:
846: + A - Jacobian matrix
847: . B - optional preconditioning matrix
848: - flag - flag indicating matrix structure
850: Notes:
851: Most users should not need to explicitly call this routine, as it
852: is used internally within the nonlinear solvers.
854: See KSPSetOperators() for important information about setting the
855: flag parameter.
857: Level: developer
859: .keywords: SNES, compute, Jacobian, matrix
861: .seealso: SNESSetJacobian(), KSPSetOperators()
862: @*/
863: PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
864: {
872: if (!snes->computejacobian) return(0);
873: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
874: *flg = DIFFERENT_NONZERO_PATTERN;
875: PetscStackPush("SNES user Jacobian function");
876: CHKMEMQ;
877: (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP);
878: CHKMEMQ;
879: PetscStackPop;
880: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
881: /* make sure user returned a correct Jacobian and preconditioner */
884: return(0);
885: }
889: /*@C
890: SNESSetJacobian - Sets the function to compute Jacobian as well as the
891: location to store the matrix.
893: Collective on SNES and Mat
895: Input Parameters:
896: + snes - the SNES context
897: . A - Jacobian matrix
898: . B - preconditioner matrix (usually same as the Jacobian)
899: . func - Jacobian evaluation routine
900: - ctx - [optional] user-defined context for private data for the
901: Jacobian evaluation routine (may be PETSC_NULL)
903: Calling sequence of func:
904: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
906: + x - input vector
907: . A - Jacobian matrix
908: . B - preconditioner matrix, usually the same as A
909: . flag - flag indicating information about the preconditioner matrix
910: structure (same as flag in KSPSetOperators())
911: - ctx - [optional] user-defined Jacobian context
913: Notes:
914: See KSPSetOperators() for important information about setting the flag
915: output parameter in the routine func(). Be sure to read this information!
917: The routine func() takes Mat * as the matrix arguments rather than Mat.
918: This allows the Jacobian evaluation routine to replace A and/or B with a
919: completely new new matrix structure (not just different matrix elements)
920: when appropriate, for instance, if the nonzero structure is changing
921: throughout the global iterations.
923: Level: beginner
925: .keywords: SNES, nonlinear, set, Jacobian, matrix
927: .seealso: KSPSetOperators(), SNESSetFunction(), MatSNESMFComputeJacobian(), SNESDefaultComputeJacobianColor()
928: @*/
929: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
930: {
939: if (func) snes->computejacobian = func;
940: if (ctx) snes->jacP = ctx;
941: if (A) {
942: if (snes->jacobian) {MatDestroy(snes->jacobian);}
943: snes->jacobian = A;
944: PetscObjectReference((PetscObject)A);
945: }
946: if (B) {
947: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
948: snes->jacobian_pre = B;
949: PetscObjectReference((PetscObject)B);
950: }
951: KSPSetOperators(snes->ksp,A,B,SAME_NONZERO_PATTERN);
952: return(0);
953: }
957: /*@C
958: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
959: provided context for evaluating the Jacobian.
961: Not Collective, but Mat object will be parallel if SNES object is
963: Input Parameter:
964: . snes - the nonlinear solver context
966: Output Parameters:
967: + A - location to stash Jacobian matrix (or PETSC_NULL)
968: . B - location to stash preconditioner matrix (or PETSC_NULL)
969: . func - location to put Jacobian function (or PETSC_NULL)
970: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
972: Level: advanced
974: .seealso: SNESSetJacobian(), SNESComputeJacobian()
975: @*/
976: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
977: {
980: if (A) *A = snes->jacobian;
981: if (B) *B = snes->jacobian_pre;
982: if (func) *func = snes->computejacobian;
983: if (ctx) *ctx = snes->jacP;
984: return(0);
985: }
987: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
988: EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
992: /*@
993: SNESSetUp - Sets up the internal data structures for the later use
994: of a nonlinear solver.
996: Collective on SNES
998: Input Parameters:
999: . snes - the SNES context
1001: Notes:
1002: For basic use of the SNES solvers the user need not explicitly call
1003: SNESSetUp(), since these actions will automatically occur during
1004: the call to SNESSolve(). However, if one wishes to control this
1005: phase separately, SNESSetUp() should be called after SNESCreate()
1006: and optional routines of the form SNESSetXXX(), but before SNESSolve().
1008: Level: advanced
1010: .keywords: SNES, nonlinear, setup
1012: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1013: @*/
1014: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes)
1015: {
1017: PetscTruth flg, iseqtr;
1021: if (snes->setupcalled) return(0);
1023: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
1024: /*
1025: This version replaces the user provided Jacobian matrix with a
1026: matrix-free version but still employs the user-provided preconditioner matrix
1027: */
1028: if (flg) {
1029: Mat J;
1030: MatCreateSNESMF(snes,snes->vec_sol,&J);
1031: MatSNESMFSetFromOptions(J);
1032: PetscInfo(snes,"Setting default matrix-free operator routines\n");
1033: SNESSetJacobian(snes,J,0,0,0);
1034: MatDestroy(J);
1035: }
1037: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1038: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
1039: if (flg) {
1040: Mat J;
1041: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1042: SNESSetJacobian(snes,J,0,0,0);
1043: MatDestroy(J);
1044: }
1045: #endif
1047: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
1048: /*
1049: This version replaces both the user-provided Jacobian and the user-
1050: provided preconditioner matrix with the default matrix free version.
1051: */
1052: if (flg) {
1053: Mat J;
1054: KSP ksp;
1055: PC pc;
1057: MatCreateSNESMF(snes,snes->vec_sol,&J);
1058: MatSNESMFSetFromOptions(J);
1059: PetscInfo(snes,"Setting default matrix-free operator and preconditioner routines;\nThat is no preconditioner is being used.\n");
1060: SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);
1061: MatDestroy(J);
1063: /* force no preconditioner */
1064: SNESGetKSP(snes,&ksp);
1065: KSPGetPC(ksp,&pc);
1066: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1067: if (!flg) {
1068: PCSetType(pc,PCNONE);
1069: }
1070: }
1072: if (!snes->vec_func && !snes->afine) {
1073: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1074: }
1075: if (!snes->computefunction && !snes->afine) {
1076: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1077: }
1078: if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1079: if (snes->vec_func == snes->vec_sol) {
1080: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1081: }
1083: /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
1084: PetscTypeCompare((PetscObject)snes,SNESTR,&iseqtr);
1085: if (snes->ksp_ewconv && !iseqtr) {
1086: KSP ksp;
1087: SNESGetKSP(snes,&ksp);
1088: KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,snes);
1089: }
1091: if (snes->setup) {(*snes->setup)(snes);}
1092: snes->setupcalled = PETSC_TRUE;
1093: return(0);
1094: }
1098: /*@
1099: SNESDestroy - Destroys the nonlinear solver context that was created
1100: with SNESCreate().
1102: Collective on SNES
1104: Input Parameter:
1105: . snes - the SNES context
1107: Level: beginner
1109: .keywords: SNES, nonlinear, destroy
1111: .seealso: SNESCreate(), SNESSolve()
1112: @*/
1113: PetscErrorCode PETSCSNES_DLLEXPORT SNESDestroy(SNES snes)
1114: {
1119: if (--snes->refct > 0) return(0);
1121: /* if memory was published with AMS then destroy it */
1122: PetscObjectDepublish(snes);
1124: if (snes->destroy) {(*(snes)->destroy)(snes);}
1125: PetscFree(snes->kspconvctx);
1126: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1127: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1128: if (snes->afine) {VecDestroy(snes->afine);}
1129: KSPDestroy(snes->ksp);
1130: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1131: SNESClearMonitor(snes);
1132: PetscHeaderDestroy(snes);
1133: return(0);
1134: }
1136: /* ----------- Routines to set solver parameters ---------- */
1140: /*@
1141: SNESSetTolerances - Sets various parameters used in convergence tests.
1143: Collective on SNES
1145: Input Parameters:
1146: + snes - the SNES context
1147: . abstol - absolute convergence tolerance
1148: . rtol - relative convergence tolerance
1149: . stol - convergence tolerance in terms of the norm
1150: of the change in the solution between steps
1151: . maxit - maximum number of iterations
1152: - maxf - maximum number of function evaluations
1154: Options Database Keys:
1155: + -snes_atol <abstol> - Sets abstol
1156: . -snes_rtol <rtol> - Sets rtol
1157: . -snes_stol <stol> - Sets stol
1158: . -snes_max_it <maxit> - Sets maxit
1159: - -snes_max_funcs <maxf> - Sets maxf
1161: Notes:
1162: The default maximum number of iterations is 50.
1163: The default maximum number of function evaluations is 1000.
1165: Level: intermediate
1167: .keywords: SNES, nonlinear, set, convergence, tolerances
1169: .seealso: SNESSetTrustRegionTolerance()
1170: @*/
1171: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1172: {
1175: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1176: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1177: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1178: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1179: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1180: return(0);
1181: }
1185: /*@
1186: SNESGetTolerances - Gets various parameters used in convergence tests.
1188: Not Collective
1190: Input Parameters:
1191: + snes - the SNES context
1192: . abstol - absolute convergence tolerance
1193: . rtol - relative convergence tolerance
1194: . stol - convergence tolerance in terms of the norm
1195: of the change in the solution between steps
1196: . maxit - maximum number of iterations
1197: - maxf - maximum number of function evaluations
1199: Notes:
1200: The user can specify PETSC_NULL for any parameter that is not needed.
1202: Level: intermediate
1204: .keywords: SNES, nonlinear, get, convergence, tolerances
1206: .seealso: SNESSetTolerances()
1207: @*/
1208: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetTolerances(SNES snes,PetscReal *abstol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1209: {
1212: if (abstol) *abstol = snes->abstol;
1213: if (rtol) *rtol = snes->rtol;
1214: if (stol) *stol = snes->xtol;
1215: if (maxit) *maxit = snes->max_its;
1216: if (maxf) *maxf = snes->max_funcs;
1217: return(0);
1218: }
1222: /*@
1223: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1225: Collective on SNES
1227: Input Parameters:
1228: + snes - the SNES context
1229: - tol - tolerance
1230:
1231: Options Database Key:
1232: . -snes_trtol <tol> - Sets tol
1234: Level: intermediate
1236: .keywords: SNES, nonlinear, set, trust region, tolerance
1238: .seealso: SNESSetTolerances()
1239: @*/
1240: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1241: {
1244: snes->deltatol = tol;
1245: return(0);
1246: }
1248: /*
1249: Duplicate the lg monitors for SNES from KSP; for some reason with
1250: dynamic libraries things don't work under Sun4 if we just use
1251: macros instead of functions
1252: */
1255: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitor(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1256: {
1261: KSPLGMonitor((KSP)snes,it,norm,ctx);
1262: return(0);
1263: }
1267: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitorCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1268: {
1272: KSPLGMonitorCreate(host,label,x,y,m,n,draw);
1273: return(0);
1274: }
1278: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitorDestroy(PetscDrawLG draw)
1279: {
1283: KSPLGMonitorDestroy(draw);
1284: return(0);
1285: }
1287: /* ------------ Routines to set performance monitoring options ----------- */
1291: /*@C
1292: SNESSetMonitor - Sets an ADDITIONAL function that is to be used at every
1293: iteration of the nonlinear solver to display the iteration's
1294: progress.
1296: Collective on SNES
1298: Input Parameters:
1299: + snes - the SNES context
1300: . func - monitoring routine
1301: . mctx - [optional] user-defined context for private data for the
1302: monitor routine (use PETSC_NULL if no context is desired)
1303: - monitordestroy - [optional] routine that frees monitor context
1304: (may be PETSC_NULL)
1306: Calling sequence of func:
1307: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1309: + snes - the SNES context
1310: . its - iteration number
1311: . norm - 2-norm function value (may be estimated)
1312: - mctx - [optional] monitoring context
1314: Options Database Keys:
1315: + -snes_monitor - sets SNESDefaultMonitor()
1316: . -snes_xmonitor - sets line graph monitor,
1317: uses SNESLGMonitorCreate()
1318: _ -snes_cancelmonitors - cancels all monitors that have
1319: been hardwired into a code by
1320: calls to SNESSetMonitor(), but
1321: does not cancel those set via
1322: the options database.
1324: Notes:
1325: Several different monitoring routines may be set by calling
1326: SNESSetMonitor() multiple times; all will be called in the
1327: order in which they were set.
1329: Level: intermediate
1331: .keywords: SNES, nonlinear, set, monitor
1333: .seealso: SNESDefaultMonitor(), SNESClearMonitor()
1334: @*/
1335: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMonitor(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1336: {
1339: if (snes->numbermonitors >= MAXSNESMONITORS) {
1340: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1341: }
1342: snes->monitor[snes->numbermonitors] = func;
1343: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1344: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1345: return(0);
1346: }
1350: /*@C
1351: SNESClearMonitor - Clears all the monitor functions for a SNES object.
1353: Collective on SNES
1355: Input Parameters:
1356: . snes - the SNES context
1358: Options Database Key:
1359: . -snes_cancelmonitors - cancels all monitors that have been hardwired
1360: into a code by calls to SNESSetMonitor(), but does not cancel those
1361: set via the options database
1363: Notes:
1364: There is no way to clear one specific monitor from a SNES object.
1366: Level: intermediate
1368: .keywords: SNES, nonlinear, set, monitor
1370: .seealso: SNESDefaultMonitor(), SNESSetMonitor()
1371: @*/
1372: PetscErrorCode PETSCSNES_DLLEXPORT SNESClearMonitor(SNES snes)
1373: {
1375: PetscInt i;
1379: for (i=0; i<snes->numbermonitors; i++) {
1380: if (snes->monitordestroy[i]) {
1381: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1382: }
1383: }
1384: snes->numbermonitors = 0;
1385: return(0);
1386: }
1390: /*@C
1391: SNESSetConvergenceTest - Sets the function that is to be used
1392: to test for convergence of the nonlinear iterative solution.
1394: Collective on SNES
1396: Input Parameters:
1397: + snes - the SNES context
1398: . func - routine to test for convergence
1399: - cctx - [optional] context for private data for the convergence routine
1400: (may be PETSC_NULL)
1402: Calling sequence of func:
1403: $ PetscErrorCode func (SNES snes,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1405: + snes - the SNES context
1406: . cctx - [optional] convergence context
1407: . reason - reason for convergence/divergence
1408: . xnorm - 2-norm of current iterate
1409: . gnorm - 2-norm of current step
1410: - f - 2-norm of function
1412: Level: advanced
1414: .keywords: SNES, nonlinear, set, convergence, test
1416: .seealso: SNESConverged_LS(), SNESConverged_TR()
1417: @*/
1418: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1419: {
1422: (snes)->converged = func;
1423: (snes)->cnvP = cctx;
1424: return(0);
1425: }
1429: /*@
1430: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1432: Not Collective
1434: Input Parameter:
1435: . snes - the SNES context
1437: Output Parameter:
1438: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1439: manual pages for the individual convergence tests for complete lists
1441: Level: intermediate
1443: Notes: Can only be called after the call the SNESSolve() is complete.
1445: .keywords: SNES, nonlinear, set, convergence, test
1447: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1448: @*/
1449: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1450: {
1454: *reason = snes->reason;
1455: return(0);
1456: }
1460: /*@
1461: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1463: Collective on SNES
1465: Input Parameters:
1466: + snes - iterative context obtained from SNESCreate()
1467: . a - array to hold history
1468: . its - integer array holds the number of linear iterations for each solve.
1469: . na - size of a and its
1470: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1471: else it continues storing new values for new nonlinear solves after the old ones
1473: Notes:
1474: If set, this array will contain the function norms computed
1475: at each step.
1477: This routine is useful, e.g., when running a code for purposes
1478: of accurate performance monitoring, when no I/O should be done
1479: during the section of code that is being timed.
1481: Level: intermediate
1483: .keywords: SNES, set, convergence, history
1485: .seealso: SNESGetConvergenceHistory()
1487: @*/
1488: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt *its,PetscInt na,PetscTruth reset)
1489: {
1493: snes->conv_hist = a;
1494: snes->conv_hist_its = its;
1495: snes->conv_hist_max = na;
1496: snes->conv_hist_reset = reset;
1497: return(0);
1498: }
1502: /*@C
1503: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1505: Collective on SNES
1507: Input Parameter:
1508: . snes - iterative context obtained from SNESCreate()
1510: Output Parameters:
1511: . a - array to hold history
1512: . its - integer array holds the number of linear iterations (or
1513: negative if not converged) for each solve.
1514: - na - size of a and its
1516: Notes:
1517: The calling sequence for this routine in Fortran is
1518: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1520: This routine is useful, e.g., when running a code for purposes
1521: of accurate performance monitoring, when no I/O should be done
1522: during the section of code that is being timed.
1524: Level: intermediate
1526: .keywords: SNES, get, convergence, history
1528: .seealso: SNESSetConvergencHistory()
1530: @*/
1531: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1532: {
1535: if (a) *a = snes->conv_hist;
1536: if (its) *its = snes->conv_hist_its;
1537: if (na) *na = snes->conv_hist_len;
1538: return(0);
1539: }
1543: /*@C
1544: SNESSetUpdate - Sets the general-purpose update function called
1545: at the beginning o every iteration of the nonlinear solve. Specifically
1546: it is called just before the Jacobian is "evaluated".
1548: Collective on SNES
1550: Input Parameters:
1551: . snes - The nonlinear solver context
1552: . func - The function
1554: Calling sequence of func:
1555: . func (SNES snes, PetscInt step);
1557: . step - The current step of the iteration
1559: Level: intermediate
1561: .keywords: SNES, update
1563: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1564: @*/
1565: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1566: {
1569: snes->update = func;
1570: return(0);
1571: }
1575: /*@
1576: SNESDefaultUpdate - The default update function which does nothing.
1578: Not collective
1580: Input Parameters:
1581: . snes - The nonlinear solver context
1582: . step - The current step of the iteration
1584: Level: intermediate
1586: .keywords: SNES, update
1587: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultSolutionBC()
1588: @*/
1589: PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step)
1590: {
1592: return(0);
1593: }
1597: /*
1598: SNESScaleStep_Private - Scales a step so that its length is less than the
1599: positive parameter delta.
1601: Input Parameters:
1602: + snes - the SNES context
1603: . y - approximate solution of linear system
1604: . fnorm - 2-norm of current function
1605: - delta - trust region size
1607: Output Parameters:
1608: + gpnorm - predicted function norm at the new point, assuming local
1609: linearization. The value is zero if the step lies within the trust
1610: region, and exceeds zero otherwise.
1611: - ynorm - 2-norm of the step
1613: Note:
1614: For non-trust region methods such as SNESLS, the parameter delta
1615: is set to be the maximum allowable step size.
1617: .keywords: SNES, nonlinear, scale, step
1618: */
1619: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1620: {
1621: PetscReal nrm;
1622: PetscScalar cnorm;
1630: VecNorm(y,NORM_2,&nrm);
1631: if (nrm > *delta) {
1632: nrm = *delta/nrm;
1633: *gpnorm = (1.0 - nrm)*(*fnorm);
1634: cnorm = nrm;
1635: VecScale(y,cnorm);
1636: *ynorm = *delta;
1637: } else {
1638: *gpnorm = 0.0;
1639: *ynorm = nrm;
1640: }
1641: return(0);
1642: }
1646: /*@
1647: SNESSolve - Solves a nonlinear system F(x) = b.
1648: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
1650: Collective on SNES
1652: Input Parameters:
1653: + snes - the SNES context
1654: . b - the constant part of the equation, or PETSC_NULL to use zero.
1655: - x - the solution vector, or PETSC_NULL if it was set with SNESSetSolution()
1657: Notes:
1658: The user should initialize the vector,x, with the initial guess
1659: for the nonlinear solve prior to calling SNESSolve. In particular,
1660: to employ an initial guess of zero, the user should explicitly set
1661: this vector to zero by calling VecSet().
1663: Level: beginner
1665: .keywords: SNES, nonlinear, solve
1667: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetRhs(), SNESSetSolution()
1668: @*/
1669: PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x)
1670: {
1672: PetscTruth flg;
1673: char filename[PETSC_MAX_PATH_LEN];
1674: PetscViewer viewer;
1678: if (!snes->solve) SETERRQ(PETSC_ERR_ORDER,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1680: if (b) {
1681: SNESSetRhs(snes, b);
1682: if (!snes->vec_func) {
1683: Vec r;
1685: VecDuplicate(b, &r);
1686: SNESSetFunction(snes, r, PETSC_NULL, PETSC_NULL);
1687: }
1688: }
1689: if (x) {
1692: } else {
1693: SNESGetSolution(snes, &x);
1694: if (!x) {
1695: VecDuplicate(snes->vec_func_always, &x);
1696: }
1697: }
1698: snes->vec_sol = snes->vec_sol_always = x;
1699: if (!snes->setupcalled) {
1700: SNESSetUp(snes);
1701: }
1702: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1703: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
1704: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1706: PetscExceptionTry1((*(snes)->solve)(snes),PETSC_ERR_ARG_DOMAIN);
1707: if (PetscExceptionValue(ierr)) {
1708: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
1709: PetscErrorCode pPetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(pierr);
1710: } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) {
1711: /* translate exception into SNES not converged reason */
1712: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
1713: 0;
1714: }
1715:
1717: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
1718: PetscOptionsGetString(snes->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
1719: if (flg && !PetscPreLoadingOn) {
1720: PetscViewerASCIIOpen(snes->comm,filename,&viewer);
1721: SNESView(snes,viewer);
1722: PetscViewerDestroy(viewer);
1723: }
1725: PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);
1726: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1727: if (snes->printreason) {
1728: if (snes->reason > 0) {
1729: PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1730: } else {
1731: PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1732: }
1733: }
1735: return(0);
1736: }
1738: /* --------- Internal routines for SNES Package --------- */
1742: /*@C
1743: SNESSetType - Sets the method for the nonlinear solver.
1745: Collective on SNES
1747: Input Parameters:
1748: + snes - the SNES context
1749: - type - a known method
1751: Options Database Key:
1752: . -snes_type <type> - Sets the method; use -help for a list
1753: of available methods (for instance, ls or tr)
1755: Notes:
1756: See "petsc/include/petscsnes.h" for available methods (for instance)
1757: + SNESLS - Newton's method with line search
1758: (systems of nonlinear equations)
1759: . SNESTR - Newton's method with trust region
1760: (systems of nonlinear equations)
1762: Normally, it is best to use the SNESSetFromOptions() command and then
1763: set the SNES solver type from the options database rather than by using
1764: this routine. Using the options database provides the user with
1765: maximum flexibility in evaluating the many nonlinear solvers.
1766: The SNESSetType() routine is provided for those situations where it
1767: is necessary to set the nonlinear solver independently of the command
1768: line or options database. This might be the case, for example, when
1769: the choice of solver changes during the execution of the program,
1770: and the user's application is taking responsibility for choosing the
1771: appropriate method.
1773: Level: intermediate
1775: .keywords: SNES, set, type
1777: .seealso: SNESType, SNESCreate()
1779: @*/
1780: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type)
1781: {
1782: PetscErrorCode ierr,(*r)(SNES);
1783: PetscTruth match;
1789: PetscTypeCompare((PetscObject)snes,type,&match);
1790: if (match) return(0);
1792: if (snes->setupcalled) {
1793: snes->setupcalled = PETSC_FALSE;
1794: (*(snes)->destroy)(snes);
1795: snes->data = 0;
1796: }
1798: /* Get the function pointers for the iterative method requested */
1799: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
1800: PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);
1801: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1802: PetscFree(snes->data);
1803: snes->data = 0;
1804: (*r)(snes);
1805: PetscObjectChangeTypeName((PetscObject)snes,type);
1806: return(0);
1807: }
1810: /* --------------------------------------------------------------------- */
1813: /*@
1814: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1815: registered by SNESRegisterDynamic().
1817: Not Collective
1819: Level: advanced
1821: .keywords: SNES, nonlinear, register, destroy
1823: .seealso: SNESRegisterAll(), SNESRegisterAll()
1824: @*/
1825: PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void)
1826: {
1830: if (SNESList) {
1831: PetscFListDestroy(&SNESList);
1832: SNESList = 0;
1833: }
1834: SNESRegisterAllCalled = PETSC_FALSE;
1835: return(0);
1836: }
1840: /*@C
1841: SNESGetType - Gets the SNES method type and name (as a string).
1843: Not Collective
1845: Input Parameter:
1846: . snes - nonlinear solver context
1848: Output Parameter:
1849: . type - SNES method (a character string)
1851: Level: intermediate
1853: .keywords: SNES, nonlinear, get, type, name
1854: @*/
1855: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type)
1856: {
1860: *type = snes->type_name;
1861: return(0);
1862: }
1866: /*@
1867: SNESGetSolution - Returns the vector where the approximate solution is
1868: stored.
1870: Not Collective, but Vec is parallel if SNES is parallel
1872: Input Parameter:
1873: . snes - the SNES context
1875: Output Parameter:
1876: . x - the solution
1878: Level: intermediate
1880: .keywords: SNES, nonlinear, get, solution
1882: .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
1883: @*/
1884: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x)
1885: {
1889: *x = snes->vec_sol_always;
1890: return(0);
1891: }
1895: /*@
1896: SNESSetSolution - Sets the vector where the approximate solution is stored.
1898: Not Collective, but Vec is parallel if SNES is parallel
1900: Input Parameters:
1901: + snes - the SNES context
1902: - x - the solution
1904: Output Parameter:
1906: Level: intermediate
1908: Notes: this is not normally used, rather one simply calls SNESSolve() with
1909: the appropriate solution vector.
1911: .keywords: SNES, nonlinear, set, solution
1913: .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
1914: @*/
1915: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetSolution(SNES snes,Vec x)
1916: {
1921: snes->vec_sol_always = x;
1922: return(0);
1923: }
1927: /*@
1928: SNESGetSolutionUpdate - Returns the vector where the solution update is
1929: stored.
1931: Not Collective, but Vec is parallel if SNES is parallel
1933: Input Parameter:
1934: . snes - the SNES context
1936: Output Parameter:
1937: . x - the solution update
1939: Level: advanced
1941: .keywords: SNES, nonlinear, get, solution, update
1943: .seealso: SNESGetSolution(), SNESGetFunction
1944: @*/
1945: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x)
1946: {
1950: *x = snes->vec_sol_update_always;
1951: return(0);
1952: }
1956: /*@C
1957: SNESGetFunction - Returns the vector where the function is stored.
1959: Not Collective, but Vec is parallel if SNES is parallel
1961: Input Parameter:
1962: . snes - the SNES context
1964: Output Parameter:
1965: + r - the function (or PETSC_NULL)
1966: . func - the function (or PETSC_NULL)
1967: - ctx - the function context (or PETSC_NULL)
1969: Level: advanced
1971: .keywords: SNES, nonlinear, get, function
1973: .seealso: SNESSetFunction(), SNESGetSolution()
1974: @*/
1975: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
1976: {
1979: if (r) *r = snes->vec_func_always;
1980: if (func) *func = snes->computefunction;
1981: if (ctx) *ctx = snes->funP;
1982: return(0);
1983: }
1987: /*@C
1988: SNESSetOptionsPrefix - Sets the prefix used for searching for all
1989: SNES options in the database.
1991: Collective on SNES
1993: Input Parameter:
1994: + snes - the SNES context
1995: - prefix - the prefix to prepend to all option names
1997: Notes:
1998: A hyphen (-) must NOT be given at the beginning of the prefix name.
1999: The first character of all runtime options is AUTOMATICALLY the hyphen.
2001: Level: advanced
2003: .keywords: SNES, set, options, prefix, database
2005: .seealso: SNESSetFromOptions()
2006: @*/
2007: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[])
2008: {
2013: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2014: KSPSetOptionsPrefix(snes->ksp,prefix);
2015: return(0);
2016: }
2020: /*@C
2021: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
2022: SNES options in the database.
2024: Collective on SNES
2026: Input Parameters:
2027: + snes - the SNES context
2028: - prefix - the prefix to prepend to all option names
2030: Notes:
2031: A hyphen (-) must NOT be given at the beginning of the prefix name.
2032: The first character of all runtime options is AUTOMATICALLY the hyphen.
2034: Level: advanced
2036: .keywords: SNES, append, options, prefix, database
2038: .seealso: SNESGetOptionsPrefix()
2039: @*/
2040: PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2041: {
2043:
2046: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2047: KSPAppendOptionsPrefix(snes->ksp,prefix);
2048: return(0);
2049: }
2053: /*@C
2054: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2055: SNES options in the database.
2057: Not Collective
2059: Input Parameter:
2060: . snes - the SNES context
2062: Output Parameter:
2063: . prefix - pointer to the prefix string used
2065: Notes: On the fortran side, the user should pass in a string 'prifix' of
2066: sufficient length to hold the prefix.
2068: Level: advanced
2070: .keywords: SNES, get, options, prefix, database
2072: .seealso: SNESAppendOptionsPrefix()
2073: @*/
2074: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2075: {
2080: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2081: return(0);
2082: }
2087: /*@C
2088: SNESRegister - See SNESRegisterDynamic()
2090: Level: advanced
2091: @*/
2092: PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2093: {
2094: char fullname[PETSC_MAX_PATH_LEN];
2098: PetscFListConcat(path,name,fullname);
2099: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2100: return(0);
2101: }
2105: PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes)
2106: {
2108: PetscInt N,i,j;
2109: Vec u,uh,fh;
2110: PetscScalar value;
2111: PetscReal norm;
2114: SNESGetSolution(snes,&u);
2115: VecDuplicate(u,&uh);
2116: VecDuplicate(u,&fh);
2118: /* currently only works for sequential */
2119: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2120: VecGetSize(u,&N);
2121: for (i=0; i<N; i++) {
2122: VecCopy(u,uh);
2123: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2124: for (j=-10; j<11; j++) {
2125: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2126: VecSetValue(uh,i,value,ADD_VALUES);
2127: SNESComputeFunction(snes,uh,fh);
2128: VecNorm(fh,NORM_2,&norm);
2129: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2130: value = -value;
2131: VecSetValue(uh,i,value,ADD_VALUES);
2132: }
2133: }
2134: VecDestroy(uh);
2135: VecDestroy(fh);
2136: return(0);
2137: }