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 - prints residual norm at each iteration
157: . -snes_vecmonitor - plots solution at each iteration
158: . -snes_vecmonitor_update - plots update to solution at each iteration
159: . -snes_xmonitor - plots residual norm at each iteration
160: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
161: . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
162: - -snes_print_converged_reason - print the reason for convergence/divergence after each solve
164: Options Database for Eisenstat-Walker method:
165: + -snes_ksp_ew_conv - use Eisenstat-Walker method for determining linear system convergence
166: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
167: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
168: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
169: . -snes_ksp_ew_gamma <gamma> - Sets gamma
170: . -snes_ksp_ew_alpha <alpha> - Sets alpha
171: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
172: - -snes_ksp_ew_threshold <threshold> - Sets threshold
174: Notes:
175: To see all options, run your program with the -help option or consult
176: the users manual.
178: Level: beginner
180: .keywords: SNES, nonlinear, set, options, database
182: .seealso: SNESSetOptionsPrefix()
183: @*/
184: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFromOptions(SNES snes)
185: {
186: KSP ksp;
187: SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
188: PetscTruth flg;
189: PetscErrorCode ierr;
190: PetscInt i;
191: const char *deft;
192: char type[256];
197: PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");
198: if (snes->type_name) {
199: deft = snes->type_name;
200: } else {
201: deft = SNESLS;
202: }
204: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
205: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
206: if (flg) {
207: SNESSetType(snes,type);
208: } else if (!snes->type_name) {
209: SNESSetType(snes,deft);
210: }
211: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
213: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
214: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);
216: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
217: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
218: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
219: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
220: PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
221: if (flg) {
222: snes->printreason = PETSC_TRUE;
223: }
225: PetscOptionsTruth("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetParametersEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);
227: PetscOptionsInt("-snes_ksp_ew_version","Version 1 or 2","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);
228: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
229: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
230: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);
231: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);
232: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);
233: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);
235: PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);
236: if (flg) {snes->converged = 0;}
237: PetscOptionsName("-snes_cancelmonitors","Remove all monitors","SNESClearMonitor",&flg);
238: if (flg) {SNESClearMonitor(snes);}
239: PetscOptionsName("-snes_monitor","Monitor norm of function","SNESDefaultMonitor",&flg);
240: if (flg) {SNESSetMonitor(snes,SNESDefaultMonitor,0,0);}
241: PetscOptionsName("-snes_ratiomonitor","Monitor norm of function","SNESSetRatioMonitor",&flg);
242: if (flg) {SNESSetRatioMonitor(snes);}
243: PetscOptionsName("-snes_smonitor","Monitor norm of function (fewer digits)","SNESDefaultSMonitor",&flg);
244: if (flg) {SNESSetMonitor(snes,SNESDefaultSMonitor,0,0);}
245: PetscOptionsName("-snes_vecmonitor","Plot solution at each iteration","SNESVecViewMonitor",&flg);
246: if (flg) {SNESSetMonitor(snes,SNESVecViewMonitor,0,0);}
247: PetscOptionsName("-snes_vecmonitor_update","Plot correction at each iteration","SNESVecViewUpdateMonitor",&flg);
248: if (flg) {SNESSetMonitor(snes,SNESVecViewUpdateMonitor,0,0);}
249: PetscOptionsName("-snes_vecmonitor_residual","Plot residual at each iteration","SNESVecViewResidualMonitor",&flg);
250: if (flg) {SNESSetMonitor(snes,SNESVecViewResidualMonitor,0,0);}
251: PetscOptionsName("-snes_xmonitor","Plot function norm at each iteration","SNESLGMonitor",&flg);
252: if (flg) {SNESSetMonitor(snes,SNESLGMonitor,PETSC_NULL,PETSC_NULL);}
254: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
255: if (flg) {
256: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
257: PetscLogInfo((snes,"SNESSetFromOptions: Setting default finite difference Jacobian matrix\n"));
258: }
260: for(i = 0; i < numberofsetfromoptions; i++) {
261: (*othersetfromoptions[i])(snes);
262: }
264: if (snes->setfromoptions) {
265: (*snes->setfromoptions)(snes);
266: }
268: PetscOptionsEnd();
270: SNESGetKSP(snes,&ksp);
271: KSPSetFromOptions(ksp);
273: return(0);
274: }
279: /*@
280: SNESSetApplicationContext - Sets the optional user-defined context for
281: the nonlinear solvers.
283: Collective on SNES
285: Input Parameters:
286: + snes - the SNES context
287: - usrP - optional user context
289: Level: intermediate
291: .keywords: SNES, nonlinear, set, application, context
293: .seealso: SNESGetApplicationContext()
294: @*/
295: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetApplicationContext(SNES snes,void *usrP)
296: {
299: snes->user = usrP;
300: return(0);
301: }
305: /*@C
306: SNESGetApplicationContext - Gets the user-defined context for the
307: nonlinear solvers.
309: Not Collective
311: Input Parameter:
312: . snes - SNES context
314: Output Parameter:
315: . usrP - user context
317: Level: intermediate
319: .keywords: SNES, nonlinear, get, application, context
321: .seealso: SNESSetApplicationContext()
322: @*/
323: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetApplicationContext(SNES snes,void **usrP)
324: {
327: *usrP = snes->user;
328: return(0);
329: }
333: /*@
334: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
335: at this time.
337: Not Collective
339: Input Parameter:
340: . snes - SNES context
342: Output Parameter:
343: . iter - iteration number
345: Notes:
346: For example, during the computation of iteration 2 this would return 1.
348: This is useful for using lagged Jacobians (where one does not recompute the
349: Jacobian at each SNES iteration). For example, the code
350: .vb
351: SNESGetIterationNumber(snes,&it);
352: if (!(it % 2)) {
353: [compute Jacobian here]
354: }
355: .ve
356: can be used in your ComputeJacobian() function to cause the Jacobian to be
357: recomputed every second SNES iteration.
359: Level: intermediate
361: .keywords: SNES, nonlinear, get, iteration, number
362: @*/
363: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetIterationNumber(SNES snes,PetscInt* iter)
364: {
368: *iter = snes->iter;
369: return(0);
370: }
374: /*@
375: SNESGetFunctionNorm - Gets the norm of the current function that was set
376: with SNESSSetFunction().
378: Collective on SNES
380: Input Parameter:
381: . snes - SNES context
383: Output Parameter:
384: . fnorm - 2-norm of function
386: Level: intermediate
388: .keywords: SNES, nonlinear, get, function, norm
390: .seealso: SNESGetFunction()
391: @*/
392: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunctionNorm(SNES snes,PetscScalar *fnorm)
393: {
397: *fnorm = snes->norm;
398: return(0);
399: }
403: /*@
404: SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
405: attempted by the nonlinear solver.
407: Not Collective
409: Input Parameter:
410: . snes - SNES context
412: Output Parameter:
413: . nfails - number of unsuccessful steps attempted
415: Notes:
416: This counter is reset to zero for each successive call to SNESSolve().
418: Level: intermediate
420: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
421: @*/
422: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberUnsuccessfulSteps(SNES snes,PetscInt* nfails)
423: {
427: *nfails = snes->numFailures;
428: return(0);
429: }
433: /*@
434: SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps
435: attempted by the nonlinear solver before it gives up.
437: Not Collective
439: Input Parameters:
440: + snes - SNES context
441: - maxFails - maximum of unsuccessful steps
443: Level: intermediate
445: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
446: @*/
447: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMaximumUnsuccessfulSteps(SNES snes, PetscInt maxFails)
448: {
451: snes->maxFailures = maxFails;
452: return(0);
453: }
457: /*@
458: SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps
459: attempted by the nonlinear solver before it gives up.
461: Not Collective
463: Input Parameter:
464: . snes - SNES context
466: Output Parameter:
467: . maxFails - maximum of unsuccessful steps
469: Level: intermediate
471: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
472: @*/
473: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetMaximumUnsuccessfulSteps(SNES snes, PetscInt *maxFails)
474: {
478: *maxFails = snes->maxFailures;
479: return(0);
480: }
484: /*@
485: SNESGetNumberLinearIterations - Gets the total number of linear iterations
486: used by the nonlinear solver.
488: Not Collective
490: Input Parameter:
491: . snes - SNES context
493: Output Parameter:
494: . lits - number of linear iterations
496: Notes:
497: This counter is reset to zero for each successive call to SNESSolve().
499: Level: intermediate
501: .keywords: SNES, nonlinear, get, number, linear, iterations
502: @*/
503: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetNumberLinearIterations(SNES snes,PetscInt* lits)
504: {
508: *lits = snes->linear_its;
509: return(0);
510: }
514: /*@C
515: SNESGetKSP - Returns the KSP context for a SNES solver.
517: Not Collective, but if SNES object is parallel, then KSP object is parallel
519: Input Parameter:
520: . snes - the SNES context
522: Output Parameter:
523: . ksp - the KSP context
525: Notes:
526: The user can then directly manipulate the KSP context to set various
527: options, etc. Likewise, the user can then extract and manipulate the
528: KSP and PC contexts as well.
530: Level: beginner
532: .keywords: SNES, nonlinear, get, KSP, context
534: .seealso: KSPGetPC()
535: @*/
536: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetKSP(SNES snes,KSP *ksp)
537: {
541: *ksp = snes->ksp;
542: return(0);
543: }
547: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
548: {
550: return(0);
551: }
553: /* -----------------------------------------------------------*/
556: /*@C
557: SNESCreate - Creates a nonlinear solver context.
559: Collective on MPI_Comm
561: Input Parameters:
562: + comm - MPI communicator
564: Output Parameter:
565: . outsnes - the new SNES context
567: Options Database Keys:
568: + -snes_mf - Activates default matrix-free Jacobian-vector products,
569: and no preconditioning matrix
570: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
571: products, and a user-provided preconditioning matrix
572: as set by SNESSetJacobian()
573: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
575: Level: beginner
577: .keywords: SNES, nonlinear, create, context
579: .seealso: SNESSolve(), SNESDestroy(), SNES
580: @*/
581: PetscErrorCode PETSCSNES_DLLEXPORT SNESCreate(MPI_Comm comm,SNES *outsnes)
582: {
583: PetscErrorCode ierr;
584: SNES snes;
585: SNES_KSP_EW_ConvCtx *kctx;
589: *outsnes = PETSC_NULL;
590: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
591: SNESInitializePackage(PETSC_NULL);
592: #endif
594: PetscHeaderCreate(snes,_p_SNES,PetscInt,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
595: snes->bops->publish = SNESPublish_Petsc;
596: snes->max_its = 50;
597: snes->max_funcs = 10000;
598: snes->norm = 0.0;
599: snes->rtol = 1.e-8;
600: snes->ttol = 0.0;
601: snes->abstol = 1.e-50;
602: snes->xtol = 1.e-8;
603: snes->deltatol = 1.e-12;
604: snes->nfuncs = 0;
605: snes->numFailures = 0;
606: snes->maxFailures = 1;
607: snes->linear_its = 0;
608: snes->numbermonitors = 0;
609: snes->data = 0;
610: snes->view = 0;
611: snes->setupcalled = PETSC_FALSE;
612: snes->ksp_ewconv = PETSC_FALSE;
613: snes->vwork = 0;
614: snes->nwork = 0;
615: snes->conv_hist_len = 0;
616: snes->conv_hist_max = 0;
617: snes->conv_hist = PETSC_NULL;
618: snes->conv_hist_its = PETSC_NULL;
619: snes->conv_hist_reset = PETSC_TRUE;
620: snes->reason = SNES_CONVERGED_ITERATING;
622: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
623: PetscNew(SNES_KSP_EW_ConvCtx,&kctx);
624: PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));
625: snes->kspconvctx = (void*)kctx;
626: kctx->version = 2;
627: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
628: this was too large for some test cases */
629: kctx->rtol_last = 0;
630: kctx->rtol_max = .9;
631: kctx->gamma = 1.0;
632: kctx->alpha2 = .5*(1.0 + sqrt(5.0));
633: kctx->alpha = kctx->alpha2;
634: kctx->threshold = .1;
635: kctx->lresid_last = 0;
636: kctx->norm_last = 0;
638: KSPCreate(comm,&snes->ksp);
639: PetscLogObjectParent(snes,snes->ksp);
641: *outsnes = snes;
642: PetscPublishAll(snes);
643: return(0);
644: }
648: /*@C
649: SNESSetFunction - Sets the function evaluation routine and function
650: vector for use by the SNES routines in solving systems of nonlinear
651: equations.
653: Collective on SNES
655: Input Parameters:
656: + snes - the SNES context
657: . func - function evaluation routine
658: . r - vector to store function value
659: - ctx - [optional] user-defined context for private data for the
660: function evaluation routine (may be PETSC_NULL)
662: Calling sequence of func:
663: $ func (SNES snes,Vec x,Vec f,void *ctx);
665: . f - function vector
666: - ctx - optional user-defined function context
668: Notes:
669: The Newton-like methods typically solve linear systems of the form
670: $ f'(x) x = -f(x),
671: where f'(x) denotes the Jacobian matrix and f(x) is the function.
673: Level: beginner
675: .keywords: SNES, nonlinear, set, function
677: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
678: @*/
679: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
680: {
686: snes->computefunction = func;
687: snes->vec_func = snes->vec_func_always = r;
688: snes->funP = ctx;
689: return(0);
690: }
692: /* --------------------------------------------------------------- */
695: /*@C
696: SNESSetRhs - Sets the vector for solving F(x) = rhs. If rhs is not set
697: it assumes a zero right hand side.
699: Collective on SNES
701: Input Parameters:
702: + snes - the SNES context
703: - rhs - the right hand side vector or PETSC_NULL for a zero right hand side
705: Level: intermediate
707: .keywords: SNES, nonlinear, set, function, right hand side
709: .seealso: SNESGetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
710: @*/
711: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetRhs(SNES snes,Vec rhs)
712: {
717: if (rhs) {
720: PetscObjectReference((PetscObject)rhs);
721: }
722: if (snes->afine) {
723: VecDestroy(snes->afine);
724: }
725: snes->afine = rhs;
726: return(0);
727: }
731: /*@C
732: SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
733: it assumes a zero right hand side.
735: Collective on SNES
737: Input Parameter:
738: . snes - the SNES context
740: Output Parameter:
741: . rhs - the right hand side vector or PETSC_NULL for a zero right hand side
743: Level: intermediate
745: .keywords: SNES, nonlinear, get, function, right hand side
747: .seealso: SNESSetRhs(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
748: @*/
749: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetRhs(SNES snes,Vec *rhs)
750: {
754: *rhs = snes->afine;
755: return(0);
756: }
760: /*@
761: SNESComputeFunction - Calls the function that has been set with
762: SNESSetFunction().
764: Collective on SNES
766: Input Parameters:
767: + snes - the SNES context
768: - x - input vector
770: Output Parameter:
771: . y - function vector, as set by SNESSetFunction()
773: Notes:
774: SNESComputeFunction() is typically used within nonlinear solvers
775: implementations, so most users would not generally call this routine
776: themselves.
778: Level: developer
780: .keywords: SNES, nonlinear, compute, function
782: .seealso: SNESSetFunction(), SNESGetFunction()
783: @*/
784: PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeFunction(SNES snes,Vec x,Vec y)
785: {
795: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
796: if (snes->computefunction) {
797: PetscStackPush("SNES user function");
798: (*snes->computefunction)(snes,x,y,snes->funP);
799: PetscStackPop;
800: if (PetscExceptionValue(ierr)) {
801: PetscErrorCode pPetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);CHKERRQ(pierr);
802: }
803:
804: } else if (snes->afine) {
805: MatMult(snes->jacobian, x, y);
806: } else {
807: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
808: }
809: if (snes->afine) {
810: PetscScalar mone = -1.0;
811: VecAXPY(y,mone,snes->afine);
812: }
813: snes->nfuncs++;
814: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
815: return(0);
816: }
820: /*@
821: SNESComputeJacobian - Computes the Jacobian matrix that has been
822: set with SNESSetJacobian().
824: Collective on SNES and Mat
826: Input Parameters:
827: + snes - the SNES context
828: - x - input vector
830: Output Parameters:
831: + A - Jacobian matrix
832: . B - optional preconditioning matrix
833: - flag - flag indicating matrix structure
835: Notes:
836: Most users should not need to explicitly call this routine, as it
837: is used internally within the nonlinear solvers.
839: See KSPSetOperators() for important information about setting the
840: flag parameter.
842: Level: developer
844: .keywords: SNES, compute, Jacobian, matrix
846: .seealso: SNESSetJacobian(), KSPSetOperators()
847: @*/
848: PetscErrorCode PETSCSNES_DLLEXPORT SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
849: {
857: if (!snes->computejacobian) return(0);
858: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
859: *flg = DIFFERENT_NONZERO_PATTERN;
860: PetscStackPush("SNES user Jacobian function");
861: (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP);
862: PetscStackPop;
863: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
864: /* make sure user returned a correct Jacobian and preconditioner */
867: return(0);
868: }
872: /*@C
873: SNESSetJacobian - Sets the function to compute Jacobian as well as the
874: location to store the matrix.
876: Collective on SNES and Mat
878: Input Parameters:
879: + snes - the SNES context
880: . A - Jacobian matrix
881: . B - preconditioner matrix (usually same as the Jacobian)
882: . func - Jacobian evaluation routine
883: - ctx - [optional] user-defined context for private data for the
884: Jacobian evaluation routine (may be PETSC_NULL)
886: Calling sequence of func:
887: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
889: + x - input vector
890: . A - Jacobian matrix
891: . B - preconditioner matrix, usually the same as A
892: . flag - flag indicating information about the preconditioner matrix
893: structure (same as flag in KSPSetOperators())
894: - ctx - [optional] user-defined Jacobian context
896: Notes:
897: See KSPSetOperators() for important information about setting the flag
898: output parameter in the routine func(). Be sure to read this information!
900: The routine func() takes Mat * as the matrix arguments rather than Mat.
901: This allows the Jacobian evaluation routine to replace A and/or B with a
902: completely new new matrix structure (not just different matrix elements)
903: when appropriate, for instance, if the nonzero structure is changing
904: throughout the global iterations.
906: Level: beginner
908: .keywords: SNES, nonlinear, set, Jacobian, matrix
910: .seealso: KSPSetOperators(), SNESSetFunction(), , MatSNESMFComputeJacobian(), SNESDefaultComputeJacobianColor()
911: @*/
912: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
913: {
922: if (func) snes->computejacobian = func;
923: if (ctx) snes->jacP = ctx;
924: if (A) {
925: if (snes->jacobian) {MatDestroy(snes->jacobian);}
926: snes->jacobian = A;
927: PetscObjectReference((PetscObject)A);
928: }
929: if (B) {
930: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
931: snes->jacobian_pre = B;
932: PetscObjectReference((PetscObject)B);
933: }
934: KSPSetOperators(snes->ksp,A,B,SAME_NONZERO_PATTERN);
935: return(0);
936: }
940: /*@C
941: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
942: provided context for evaluating the Jacobian.
944: Not Collective, but Mat object will be parallel if SNES object is
946: Input Parameter:
947: . snes - the nonlinear solver context
949: Output Parameters:
950: + A - location to stash Jacobian matrix (or PETSC_NULL)
951: . B - location to stash preconditioner matrix (or PETSC_NULL)
952: . func - location to put Jacobian function (or PETSC_NULL)
953: - ctx - location to stash Jacobian ctx (or PETSC_NULL)
955: Level: advanced
957: .seealso: SNESSetJacobian(), SNESComputeJacobian()
958: @*/
959: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
960: {
963: if (A) *A = snes->jacobian;
964: if (B) *B = snes->jacobian_pre;
965: if (func) *func = snes->computejacobian;
966: if (ctx) *ctx = snes->jacP;
967: return(0);
968: }
970: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
971: EXTERN PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
975: /*@
976: SNESSetUp - Sets up the internal data structures for the later use
977: of a nonlinear solver.
979: Collective on SNES
981: Input Parameters:
982: . snes - the SNES context
984: Notes:
985: For basic use of the SNES solvers the user need not explicitly call
986: SNESSetUp(), since these actions will automatically occur during
987: the call to SNESSolve(). However, if one wishes to control this
988: phase separately, SNESSetUp() should be called after SNESCreate()
989: and optional routines of the form SNESSetXXX(), but before SNESSolve().
991: Level: advanced
993: .keywords: SNES, nonlinear, setup
995: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
996: @*/
997: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUp(SNES snes)
998: {
1000: PetscTruth flg, iseqtr;
1004: if (snes->setupcalled) return(0);
1006: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
1007: /*
1008: This version replaces the user provided Jacobian matrix with a
1009: matrix-free version but still employs the user-provided preconditioner matrix
1010: */
1011: if (flg) {
1012: Mat J;
1013: MatCreateSNESMF(snes,snes->vec_sol,&J);
1014: MatSNESMFSetFromOptions(J);
1015: PetscLogInfo((snes,"SNESSetUp: Setting default matrix-free operator routines\n"));
1016: SNESSetJacobian(snes,J,0,0,0);
1017: MatDestroy(J);
1018: }
1020: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE)
1021: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
1022: if (flg) {
1023: Mat J;
1024: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1025: SNESSetJacobian(snes,J,0,0,0);
1026: MatDestroy(J);
1027: }
1028: #endif
1030: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
1031: /*
1032: This version replaces both the user-provided Jacobian and the user-
1033: provided preconditioner matrix with the default matrix free version.
1034: */
1035: if (flg) {
1036: Mat J;
1037: KSP ksp;
1038: PC pc;
1040: MatCreateSNESMF(snes,snes->vec_sol,&J);
1041: MatSNESMFSetFromOptions(J);
1042: PetscLogInfo((snes,"SNESSetUp: Setting default matrix-free operator and preconditioner routines\n"));
1043: SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);
1044: MatDestroy(J);
1046: /* force no preconditioner */
1047: SNESGetKSP(snes,&ksp);
1048: KSPGetPC(ksp,&pc);
1049: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1050: if (!flg) {
1051: PCSetType(pc,PCNONE);
1052: }
1053: }
1055: if (!snes->vec_func && !snes->afine) {
1056: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1057: }
1058: if (!snes->computefunction && !snes->afine) {
1059: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1060: }
1061: if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1062: if (snes->vec_func == snes->vec_sol) {
1063: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1064: }
1066: /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
1067: PetscTypeCompare((PetscObject)snes,SNESTR,&iseqtr);
1068: if (snes->ksp_ewconv && !iseqtr) {
1069: KSP ksp;
1070: SNESGetKSP(snes,&ksp);
1071: KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,snes);
1072: }
1074: if (snes->setup) {(*snes->setup)(snes);}
1075: snes->setupcalled = PETSC_TRUE;
1076: return(0);
1077: }
1081: /*@C
1082: SNESDestroy - Destroys the nonlinear solver context that was created
1083: with SNESCreate().
1085: Collective on SNES
1087: Input Parameter:
1088: . snes - the SNES context
1090: Level: beginner
1092: .keywords: SNES, nonlinear, destroy
1094: .seealso: SNESCreate(), SNESSolve()
1095: @*/
1096: PetscErrorCode PETSCSNES_DLLEXPORT SNESDestroy(SNES snes)
1097: {
1102: if (--snes->refct > 0) return(0);
1104: /* if memory was published with AMS then destroy it */
1105: PetscObjectDepublish(snes);
1107: if (snes->destroy) {(*(snes)->destroy)(snes);}
1108: if (snes->kspconvctx) {PetscFree(snes->kspconvctx);}
1109: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1110: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1111: if (snes->afine) {VecDestroy(snes->afine);}
1112: KSPDestroy(snes->ksp);
1113: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1114: SNESClearMonitor(snes);
1115: PetscHeaderDestroy(snes);
1116: return(0);
1117: }
1119: /* ----------- Routines to set solver parameters ---------- */
1123: /*@
1124: SNESSetTolerances - Sets various parameters used in convergence tests.
1126: Collective on SNES
1128: Input Parameters:
1129: + snes - the SNES context
1130: . abstol - absolute convergence tolerance
1131: . rtol - relative convergence tolerance
1132: . stol - convergence tolerance in terms of the norm
1133: of the change in the solution between steps
1134: . maxit - maximum number of iterations
1135: - maxf - maximum number of function evaluations
1137: Options Database Keys:
1138: + -snes_atol <abstol> - Sets abstol
1139: . -snes_rtol <rtol> - Sets rtol
1140: . -snes_stol <stol> - Sets stol
1141: . -snes_max_it <maxit> - Sets maxit
1142: - -snes_max_funcs <maxf> - Sets maxf
1144: Notes:
1145: The default maximum number of iterations is 50.
1146: The default maximum number of function evaluations is 1000.
1148: Level: intermediate
1150: .keywords: SNES, nonlinear, set, convergence, tolerances
1152: .seealso: SNESSetTrustRegionTolerance()
1153: @*/
1154: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1155: {
1158: if (abstol != PETSC_DEFAULT) snes->abstol = abstol;
1159: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1160: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1161: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1162: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1163: return(0);
1164: }
1168: /*@
1169: SNESGetTolerances - Gets various parameters used in convergence tests.
1171: Not Collective
1173: Input Parameters:
1174: + snes - the SNES context
1175: . abstol - absolute convergence tolerance
1176: . rtol - relative convergence tolerance
1177: . stol - convergence tolerance in terms of the norm
1178: of the change in the solution between steps
1179: . maxit - maximum number of iterations
1180: - maxf - maximum number of function evaluations
1182: Notes:
1183: The user can specify PETSC_NULL for any parameter that is not needed.
1185: Level: intermediate
1187: .keywords: SNES, nonlinear, get, convergence, tolerances
1189: .seealso: SNESSetTolerances()
1190: @*/
1191: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetTolerances(SNES snes,PetscReal *abstol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1192: {
1195: if (abstol) *abstol = snes->abstol;
1196: if (rtol) *rtol = snes->rtol;
1197: if (stol) *stol = snes->xtol;
1198: if (maxit) *maxit = snes->max_its;
1199: if (maxf) *maxf = snes->max_funcs;
1200: return(0);
1201: }
1205: /*@
1206: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1208: Collective on SNES
1210: Input Parameters:
1211: + snes - the SNES context
1212: - tol - tolerance
1213:
1214: Options Database Key:
1215: . -snes_trtol <tol> - Sets tol
1217: Level: intermediate
1219: .keywords: SNES, nonlinear, set, trust region, tolerance
1221: .seealso: SNESSetTolerances()
1222: @*/
1223: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1224: {
1227: snes->deltatol = tol;
1228: return(0);
1229: }
1231: /*
1232: Duplicate the lg monitors for SNES from KSP; for some reason with
1233: dynamic libraries things don't work under Sun4 if we just use
1234: macros instead of functions
1235: */
1238: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitor(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1239: {
1244: KSPLGMonitor((KSP)snes,it,norm,ctx);
1245: return(0);
1246: }
1250: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitorCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1251: {
1255: KSPLGMonitorCreate(host,label,x,y,m,n,draw);
1256: return(0);
1257: }
1261: PetscErrorCode PETSCSNES_DLLEXPORT SNESLGMonitorDestroy(PetscDrawLG draw)
1262: {
1266: KSPLGMonitorDestroy(draw);
1267: return(0);
1268: }
1270: /* ------------ Routines to set performance monitoring options ----------- */
1274: /*@C
1275: SNESSetMonitor - Sets an ADDITIONAL function that is to be used at every
1276: iteration of the nonlinear solver to display the iteration's
1277: progress.
1279: Collective on SNES
1281: Input Parameters:
1282: + snes - the SNES context
1283: . func - monitoring routine
1284: . mctx - [optional] user-defined context for private data for the
1285: monitor routine (use PETSC_NULL if no context is desitre)
1286: - monitordestroy - [optional] routine that frees monitor context
1287: (may be PETSC_NULL)
1289: Calling sequence of func:
1290: $ int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)
1292: + snes - the SNES context
1293: . its - iteration number
1294: . norm - 2-norm function value (may be estimated)
1295: - mctx - [optional] monitoring context
1297: Options Database Keys:
1298: + -snes_monitor - sets SNESDefaultMonitor()
1299: . -snes_xmonitor - sets line graph monitor,
1300: uses SNESLGMonitorCreate()
1301: _ -snes_cancelmonitors - cancels all monitors that have
1302: been hardwired into a code by
1303: calls to SNESSetMonitor(), but
1304: does not cancel those set via
1305: the options database.
1307: Notes:
1308: Several different monitoring routines may be set by calling
1309: SNESSetMonitor() multiple times; all will be called in the
1310: order in which they were set.
1312: Level: intermediate
1314: .keywords: SNES, nonlinear, set, monitor
1316: .seealso: SNESDefaultMonitor(), SNESClearMonitor()
1317: @*/
1318: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetMonitor(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1319: {
1322: if (snes->numbermonitors >= MAXSNESMONITORS) {
1323: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1324: }
1325: snes->monitor[snes->numbermonitors] = func;
1326: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1327: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1328: return(0);
1329: }
1333: /*@C
1334: SNESClearMonitor - Clears all the monitor functions for a SNES object.
1336: Collective on SNES
1338: Input Parameters:
1339: . snes - the SNES context
1341: Options Database Key:
1342: . -snes_cancelmonitors - cancels all monitors that have been hardwired
1343: into a code by calls to SNESSetMonitor(), but does not cancel those
1344: set via the options database
1346: Notes:
1347: There is no way to clear one specific monitor from a SNES object.
1349: Level: intermediate
1351: .keywords: SNES, nonlinear, set, monitor
1353: .seealso: SNESDefaultMonitor(), SNESSetMonitor()
1354: @*/
1355: PetscErrorCode PETSCSNES_DLLEXPORT SNESClearMonitor(SNES snes)
1356: {
1358: PetscInt i;
1362: for (i=0; i<snes->numbermonitors; i++) {
1363: if (snes->monitordestroy[i]) {
1364: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1365: }
1366: }
1367: snes->numbermonitors = 0;
1368: return(0);
1369: }
1373: /*@C
1374: SNESSetConvergenceTest - Sets the function that is to be used
1375: to test for convergence of the nonlinear iterative solution.
1377: Collective on SNES
1379: Input Parameters:
1380: + snes - the SNES context
1381: . func - routine to test for convergence
1382: - cctx - [optional] context for private data for the convergence routine
1383: (may be PETSC_NULL)
1385: Calling sequence of func:
1386: $ PetscErrorCode func (SNES snes,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1388: + snes - the SNES context
1389: . cctx - [optional] convergence context
1390: . reason - reason for convergence/divergence
1391: . xnorm - 2-norm of current iterate
1392: . gnorm - 2-norm of current step
1393: - f - 2-norm of function
1395: Level: advanced
1397: .keywords: SNES, nonlinear, set, convergence, test
1399: .seealso: SNESConverged_LS(), SNESConverged_TR()
1400: @*/
1401: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1402: {
1405: (snes)->converged = func;
1406: (snes)->cnvP = cctx;
1407: return(0);
1408: }
1412: /*@C
1413: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1415: Not Collective
1417: Input Parameter:
1418: . snes - the SNES context
1420: Output Parameter:
1421: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1422: manual pages for the individual convergence tests for complete lists
1424: Level: intermediate
1426: Notes: Can only be called after the call the SNESSolve() is complete.
1428: .keywords: SNES, nonlinear, set, convergence, test
1430: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1431: @*/
1432: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1433: {
1437: *reason = snes->reason;
1438: return(0);
1439: }
1443: /*@
1444: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1446: Collective on SNES
1448: Input Parameters:
1449: + snes - iterative context obtained from SNESCreate()
1450: . a - array to hold history
1451: . its - integer array holds the number of linear iterations for each solve.
1452: . na - size of a and its
1453: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1454: else it continues storing new values for new nonlinear solves after the old ones
1456: Notes:
1457: If set, this array will contain the function norms computed
1458: at each step.
1460: This routine is useful, e.g., when running a code for purposes
1461: of accurate performance monitoring, when no I/O should be done
1462: during the section of code that is being timed.
1464: Level: intermediate
1466: .keywords: SNES, set, convergence, history
1468: .seealso: SNESGetConvergenceHistory()
1470: @*/
1471: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt *its,PetscInt na,PetscTruth reset)
1472: {
1476: snes->conv_hist = a;
1477: snes->conv_hist_its = its;
1478: snes->conv_hist_max = na;
1479: snes->conv_hist_reset = reset;
1480: return(0);
1481: }
1485: /*@C
1486: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1488: Collective on SNES
1490: Input Parameter:
1491: . snes - iterative context obtained from SNESCreate()
1493: Output Parameters:
1494: . a - array to hold history
1495: . its - integer array holds the number of linear iterations (or
1496: negative if not converged) for each solve.
1497: - na - size of a and its
1499: Notes:
1500: The calling sequence for this routine in Fortran is
1501: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1503: This routine is useful, e.g., when running a code for purposes
1504: of accurate performance monitoring, when no I/O should be done
1505: during the section of code that is being timed.
1507: Level: intermediate
1509: .keywords: SNES, get, convergence, history
1511: .seealso: SNESSetConvergencHistory()
1513: @*/
1514: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1515: {
1518: if (a) *a = snes->conv_hist;
1519: if (its) *its = snes->conv_hist_its;
1520: if (na) *na = snes->conv_hist_len;
1521: return(0);
1522: }
1526: /*@C
1527: SNESSetUpdate - Sets the general-purpose update function called
1528: at the beginning of every step of the iteration.
1530: Collective on SNES
1532: Input Parameters:
1533: . snes - The nonlinear solver context
1534: . func - The function
1536: Calling sequence of func:
1537: . func (SNES snes, PetscInt step);
1539: . step - The current step of the iteration
1541: Level: intermediate
1543: .keywords: SNES, update
1545: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1546: @*/
1547: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1548: {
1551: snes->update = func;
1552: return(0);
1553: }
1557: /*@
1558: SNESDefaultUpdate - The default update function which does nothing.
1560: Not collective
1562: Input Parameters:
1563: . snes - The nonlinear solver context
1564: . step - The current step of the iteration
1566: Level: intermediate
1568: .keywords: SNES, update
1569: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultSolutionBC()
1570: @*/
1571: PetscErrorCode PETSCSNES_DLLEXPORT SNESDefaultUpdate(SNES snes, PetscInt step)
1572: {
1574: return(0);
1575: }
1579: /*
1580: SNESScaleStep_Private - Scales a step so that its length is less than the
1581: positive parameter delta.
1583: Input Parameters:
1584: + snes - the SNES context
1585: . y - approximate solution of linear system
1586: . fnorm - 2-norm of current function
1587: - delta - trust region size
1589: Output Parameters:
1590: + gpnorm - predicted function norm at the new point, assuming local
1591: linearization. The value is zero if the step lies within the trust
1592: region, and exceeds zero otherwise.
1593: - ynorm - 2-norm of the step
1595: Note:
1596: For non-trust region methods such as SNESLS, the parameter delta
1597: is set to be the maximum allowable step size.
1599: .keywords: SNES, nonlinear, scale, step
1600: */
1601: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1602: {
1603: PetscReal nrm;
1604: PetscScalar cnorm;
1612: VecNorm(y,NORM_2,&nrm);
1613: if (nrm > *delta) {
1614: nrm = *delta/nrm;
1615: *gpnorm = (1.0 - nrm)*(*fnorm);
1616: cnorm = nrm;
1617: VecScale(y,cnorm);
1618: *ynorm = *delta;
1619: } else {
1620: *gpnorm = 0.0;
1621: *ynorm = nrm;
1622: }
1623: return(0);
1624: }
1628: /*@
1629: SNESSolve - Solves a nonlinear system F(x) = b.
1630: Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().
1632: Collective on SNES
1634: Input Parameters:
1635: + snes - the SNES context
1636: . b - the constant part of the equation, or PETSC_NULL to use zero.
1637: - x - the solution vector, or PETSC_NULL if it was set with SNESSetSolution()
1639: Notes:
1640: The user should initialize the vector,x, with the initial guess
1641: for the nonlinear solve prior to calling SNESSolve. In particular,
1642: to employ an initial guess of zero, the user should explicitly set
1643: this vector to zero by calling VecSet().
1645: Level: beginner
1647: .keywords: SNES, nonlinear, solve
1649: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian(), SNESSetRhs(), SNESSetSolution()
1650: @*/
1651: PetscErrorCode PETSCSNES_DLLEXPORT SNESSolve(SNES snes,Vec b,Vec x)
1652: {
1654: PetscTruth flg;
1658: if (!snes->solve) SETERRQ(PETSC_ERR_ORDER,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1660: if (b) {
1661: SNESSetRhs(snes, b);
1662: if (!snes->vec_func) {
1663: Vec r;
1665: VecDuplicate(b, &r);
1666: SNESSetFunction(snes, r, PETSC_NULL, PETSC_NULL);
1667: }
1668: }
1669: if (x) {
1672: } else {
1673: SNESGetSolution(snes, &x);
1674: if (!x) {
1675: VecDuplicate(snes->vec_func_always, &x);
1676: }
1677: }
1678: snes->vec_sol = snes->vec_sol_always = x;
1679: if (!snes->setupcalled) {
1680: SNESSetUp(snes);
1681: }
1682: if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1683: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
1684: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1686: PetscExceptionTry1((*(snes)->solve)(snes),PETSC_ERR_ARG_DOMAIN);
1687: if (PetscExceptionValue(ierr)) {
1688: /* this means that a caller above me has also tryed this exception so I don't handle it here, pass it up */
1689: PetscErrorCode pPetscLogEventEnd(SNES_Solve,snes,0,0,0);CHKERRQ(pierr);
1690: } else if (PetscExceptionCaught(ierr,PETSC_ERR_ARG_DOMAIN)) {
1691: /* translate exception into SNES not converged reason */
1692: snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
1693: 0;
1694: }
1695:
1697: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
1698: PetscOptionsHasName(snes->prefix,"-snes_view",&flg);
1699: if (flg && !PetscPreLoadingOn) { SNESView(snes,PETSC_VIEWER_STDOUT_(snes->comm)); }
1700: PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);
1701: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1702: if (snes->printreason) {
1703: if (snes->reason > 0) {
1704: PetscPrintf(snes->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1705: } else {
1706: PetscPrintf(snes->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1707: }
1708: }
1710: return(0);
1711: }
1713: /* --------- Internal routines for SNES Package --------- */
1717: /*@C
1718: SNESSetType - Sets the method for the nonlinear solver.
1720: Collective on SNES
1722: Input Parameters:
1723: + snes - the SNES context
1724: - type - a known method
1726: Options Database Key:
1727: . -snes_type <type> - Sets the method; use -help for a list
1728: of available methods (for instance, ls or tr)
1730: Notes:
1731: See "petsc/include/petscsnes.h" for available methods (for instance)
1732: + SNESLS - Newton's method with line search
1733: (systems of nonlinear equations)
1734: . SNESTR - Newton's method with trust region
1735: (systems of nonlinear equations)
1737: Normally, it is best to use the SNESSetFromOptions() command and then
1738: set the SNES solver type from the options database rather than by using
1739: this routine. Using the options database provides the user with
1740: maximum flexibility in evaluating the many nonlinear solvers.
1741: The SNESSetType() routine is provided for those situations where it
1742: is necessary to set the nonlinear solver independently of the command
1743: line or options database. This might be the case, for example, when
1744: the choice of solver changes during the execution of the program,
1745: and the user's application is taking responsibility for choosing the
1746: appropriate method.
1748: Level: intermediate
1750: .keywords: SNES, set, type
1752: .seealso: SNESType, SNESCreate()
1754: @*/
1755: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetType(SNES snes,SNESType type)
1756: {
1757: PetscErrorCode ierr,(*r)(SNES);
1758: PetscTruth match;
1764: PetscTypeCompare((PetscObject)snes,type,&match);
1765: if (match) return(0);
1767: if (snes->setupcalled) {
1768: snes->setupcalled = PETSC_FALSE;
1769: (*(snes)->destroy)(snes);
1770: snes->data = 0;
1771: }
1773: /* Get the function pointers for the iterative method requested */
1774: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
1775: PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);
1776: if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1777: if (snes->data) {PetscFree(snes->data);}
1778: snes->data = 0;
1779: (*r)(snes);
1780: PetscObjectChangeTypeName((PetscObject)snes,type);
1781: return(0);
1782: }
1785: /* --------------------------------------------------------------------- */
1788: /*@C
1789: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1790: registered by SNESRegisterDynamic().
1792: Not Collective
1794: Level: advanced
1796: .keywords: SNES, nonlinear, register, destroy
1798: .seealso: SNESRegisterAll(), SNESRegisterAll()
1799: @*/
1800: PetscErrorCode PETSCSNES_DLLEXPORT SNESRegisterDestroy(void)
1801: {
1805: if (SNESList) {
1806: PetscFListDestroy(&SNESList);
1807: SNESList = 0;
1808: }
1809: SNESRegisterAllCalled = PETSC_FALSE;
1810: return(0);
1811: }
1815: /*@C
1816: SNESGetType - Gets the SNES method type and name (as a string).
1818: Not Collective
1820: Input Parameter:
1821: . snes - nonlinear solver context
1823: Output Parameter:
1824: . type - SNES method (a character string)
1826: Level: intermediate
1828: .keywords: SNES, nonlinear, get, type, name
1829: @*/
1830: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetType(SNES snes,SNESType *type)
1831: {
1835: *type = snes->type_name;
1836: return(0);
1837: }
1841: /*@C
1842: SNESGetSolution - Returns the vector where the approximate solution is
1843: stored.
1845: Not Collective, but Vec is parallel if SNES is parallel
1847: Input Parameter:
1848: . snes - the SNES context
1850: Output Parameter:
1851: . x - the solution
1853: Level: intermediate
1855: .keywords: SNES, nonlinear, get, solution
1857: .seealso: SNESSetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
1858: @*/
1859: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolution(SNES snes,Vec *x)
1860: {
1864: *x = snes->vec_sol_always;
1865: return(0);
1866: }
1870: /*@
1871: SNESSetSolution - Sets the vector where the approximate solution is stored.
1873: Not Collective, but Vec is parallel if SNES is parallel
1875: Input Parameters:
1876: + snes - the SNES context
1877: - x - the solution
1879: Output Parameter:
1881: Level: intermediate
1883: .keywords: SNES, nonlinear, set, solution
1885: .seealso: SNESGetSolution(), SNESGetFunction(), SNESGetSolutionUpdate()
1886: @*/
1887: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetSolution(SNES snes,Vec x)
1888: {
1893: snes->vec_sol_always = x;
1894: return(0);
1895: }
1899: /*@C
1900: SNESGetSolutionUpdate - Returns the vector where the solution update is
1901: stored.
1903: Not Collective, but Vec is parallel if SNES is parallel
1905: Input Parameter:
1906: . snes - the SNES context
1908: Output Parameter:
1909: . x - the solution update
1911: Level: advanced
1913: .keywords: SNES, nonlinear, get, solution, update
1915: .seealso: SNESGetSolution(), SNESGetFunction
1916: @*/
1917: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetSolutionUpdate(SNES snes,Vec *x)
1918: {
1922: *x = snes->vec_sol_update_always;
1923: return(0);
1924: }
1928: /*@C
1929: SNESGetFunction - Returns the vector where the function is stored.
1931: Not Collective, but Vec is parallel if SNES is parallel
1933: Input Parameter:
1934: . snes - the SNES context
1936: Output Parameter:
1937: + r - the function (or PETSC_NULL)
1938: . func - the function (or PETSC_NULL)
1939: - ctx - the function context (or PETSC_NULL)
1941: Level: advanced
1943: .keywords: SNES, nonlinear, get, function
1945: .seealso: SNESSetFunction(), SNESGetSolution()
1946: @*/
1947: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
1948: {
1951: if (r) *r = snes->vec_func_always;
1952: if (func) *func = snes->computefunction;
1953: if (ctx) *ctx = snes->funP;
1954: return(0);
1955: }
1959: /*@C
1960: SNESSetOptionsPrefix - Sets the prefix used for searching for all
1961: SNES options in the database.
1963: Collective on SNES
1965: Input Parameter:
1966: + snes - the SNES context
1967: - prefix - the prefix to prepend to all option names
1969: Notes:
1970: A hyphen (-) must NOT be given at the beginning of the prefix name.
1971: The first character of all runtime options is AUTOMATICALLY the hyphen.
1973: Level: advanced
1975: .keywords: SNES, set, options, prefix, database
1977: .seealso: SNESSetFromOptions()
1978: @*/
1979: PetscErrorCode PETSCSNES_DLLEXPORT SNESSetOptionsPrefix(SNES snes,const char prefix[])
1980: {
1985: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
1986: KSPSetOptionsPrefix(snes->ksp,prefix);
1987: return(0);
1988: }
1992: /*@C
1993: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
1994: SNES options in the database.
1996: Collective on SNES
1998: Input Parameters:
1999: + snes - the SNES context
2000: - prefix - the prefix to prepend to all option names
2002: Notes:
2003: A hyphen (-) must NOT be given at the beginning of the prefix name.
2004: The first character of all runtime options is AUTOMATICALLY the hyphen.
2006: Level: advanced
2008: .keywords: SNES, append, options, prefix, database
2010: .seealso: SNESGetOptionsPrefix()
2011: @*/
2012: PetscErrorCode PETSCSNES_DLLEXPORT SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2013: {
2015:
2018: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2019: KSPAppendOptionsPrefix(snes->ksp,prefix);
2020: return(0);
2021: }
2025: /*@C
2026: SNESGetOptionsPrefix - Sets the prefix used for searching for all
2027: SNES options in the database.
2029: Not Collective
2031: Input Parameter:
2032: . snes - the SNES context
2034: Output Parameter:
2035: . prefix - pointer to the prefix string used
2037: Notes: On the fortran side, the user should pass in a string 'prifix' of
2038: sufficient length to hold the prefix.
2040: Level: advanced
2042: .keywords: SNES, get, options, prefix, database
2044: .seealso: SNESAppendOptionsPrefix()
2045: @*/
2046: PetscErrorCode PETSCSNES_DLLEXPORT SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2047: {
2052: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2053: return(0);
2054: }
2059: /*@C
2060: SNESRegister - See SNESRegisterDynamic()
2062: Level: advanced
2063: @*/
2064: PetscErrorCode PETSCSNES_DLLEXPORT SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2065: {
2066: char fullname[PETSC_MAX_PATH_LEN];
2070: PetscFListConcat(path,name,fullname);
2071: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2072: return(0);
2073: }
2077: PetscErrorCode PETSCSNES_DLLEXPORT SNESTestLocalMin(SNES snes)
2078: {
2080: PetscInt N,i,j;
2081: Vec u,uh,fh;
2082: PetscScalar value;
2083: PetscReal norm;
2086: SNESGetSolution(snes,&u);
2087: VecDuplicate(u,&uh);
2088: VecDuplicate(u,&fh);
2090: /* currently only works for sequential */
2091: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2092: VecGetSize(u,&N);
2093: for (i=0; i<N; i++) {
2094: VecCopy(u,uh);
2095: PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2096: for (j=-10; j<11; j++) {
2097: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2098: VecSetValue(uh,i,value,ADD_VALUES);
2099: SNESComputeFunction(snes,uh,fh);
2100: VecNorm(fh,NORM_2,&norm);
2101: PetscPrintf(PETSC_COMM_WORLD," j norm %D %18.16e\n",j,norm);
2102: value = -value;
2103: VecSetValue(uh,i,value,ADD_VALUES);
2104: }
2105: }
2106: VecDestroy(uh);
2107: VecDestroy(fh);
2108: return(0);
2109: }