Actual source code: snes.c
1: /*$Id: snes.c,v 1.235 2001/08/21 21:03:49 bsmith Exp $*/
3: #include src/snes/snesimpl.h
5: PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
6: PetscFList SNESList = PETSC_NULL;
8: /* Logging support */
9: int SNES_COOKIE;
10: int SNES_Solve, SNES_LineSearch, SNES_FunctionEval, SNES_JacobianEval;
12: /*@C
13: SNESView - Prints the SNES data structure.
15: Collective on SNES
17: Input Parameters:
18: + SNES - the SNES context
19: - viewer - visualization context
21: Options Database Key:
22: . -snes_view - Calls SNESView() at end of SNESSolve()
24: Notes:
25: The available visualization contexts include
26: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
27: - PETSC_VIEWER_STDOUT_WORLD - synchronized standard
28: output where only the first processor opens
29: the file. All other processors send their
30: data to the first processor to print.
32: The user can open an alternative visualization context with
33: PetscViewerASCIIOpen() - output to a specified file.
35: Level: beginner
37: .keywords: SNES, view
39: .seealso: PetscViewerASCIIOpen()
40: @*/
41: int SNESView(SNES snes,PetscViewer viewer)
42: {
43: SNES_KSP_EW_ConvCtx *kctx;
44: int ierr;
45: SLES sles;
46: char *type;
47: PetscTruth isascii,isstring;
51: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
55: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
56: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
57: if (isascii) {
58: if (snes->prefix) {
59: PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)n",snes->prefix);
60: } else {
61: PetscViewerASCIIPrintf(viewer,"SNES Object:n");
62: }
63: SNESGetType(snes,&type);
64: if (type) {
65: PetscViewerASCIIPrintf(viewer," type: %sn",type);
66: } else {
67: PetscViewerASCIIPrintf(viewer," type: not set yetn");
68: }
69: if (snes->view) {
70: PetscViewerASCIIPushTab(viewer);
71: (*snes->view)(snes,viewer);
72: PetscViewerASCIIPopTab(viewer);
73: }
74: PetscViewerASCIIPrintf(viewer," maximum iterations=%d, maximum function evaluations=%dn",snes->max_its,snes->max_funcs);
75: PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%gn",
76: snes->rtol,snes->atol,snes->xtol);
77: PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%dn",snes->linear_its);
78: PetscViewerASCIIPrintf(viewer," total number of function evaluations=%dn",snes->nfuncs);
79: if (snes->ksp_ewconv) {
80: kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
81: if (kctx) {
82: PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %d)n",kctx->version);
83: PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%gn",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
84: PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%gn",kctx->gamma,kctx->alpha,kctx->alpha2);
85: }
86: }
87: } else if (isstring) {
88: SNESGetType(snes,&type);
89: PetscViewerStringSPrintf(viewer," %-3.3s",type);
90: }
91: SNESGetSLES(snes,&sles);
92: PetscViewerASCIIPushTab(viewer);
93: SLESView(sles,viewer);
94: PetscViewerASCIIPopTab(viewer);
95: return(0);
96: }
98: /*
99: We retain a list of functions that also take SNES command
100: line options. These are called at the end SNESSetFromOptions()
101: */
102: #define MAXSETFROMOPTIONS 5
103: static int numberofsetfromoptions;
104: static int (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);
106: /*@
107: SNESAddOptionsChecker - Adds an additional function to check for SNES options.
109: Not Collective
111: Input Parameter:
112: . snescheck - function that checks for options
114: Level: developer
116: .seealso: SNESSetFromOptions()
117: @*/
118: int SNESAddOptionsChecker(int (*snescheck)(SNES))
119: {
121: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
122: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS);
123: }
125: othersetfromoptions[numberofsetfromoptions++] = snescheck;
126: return(0);
127: }
129: /*@
130: SNESSetFromOptions - Sets various SNES and SLES parameters from user options.
132: Collective on SNES
134: Input Parameter:
135: . snes - the SNES context
137: Options Database Keys:
138: + -snes_type <type> - ls, tr, umls, umtr, test
139: . -snes_stol - convergence tolerance in terms of the norm
140: of the change in the solution between steps
141: . -snes_atol <atol> - absolute tolerance of residual norm
142: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
143: . -snes_max_it <max_it> - maximum number of iterations
144: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
145: . -snes_max_fail <max_fail> - maximum number of failures
146: . -snes_trtol <trtol> - trust region tolerance
147: . -snes_no_convergence_test - skip convergence test in nonlinear or minimization
148: solver; hence iterations will continue until max_it
149: or some other criterion is reached. Saves expense
150: of convergence test
151: . -snes_monitor - prints residual norm at each iteration
152: . -snes_vecmonitor - plots solution at each iteration
153: . -snes_vecmonitor_update - plots update to solution at each iteration
154: . -snes_xmonitor - plots residual norm at each iteration
155: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
156: - -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
158: Options Database for Eisenstat-Walker method:
159: + -snes_ksp_ew_conv - use Eisenstat-Walker method for determining linear system convergence
160: . -snes_ksp_ew_version ver - version of Eisenstat-Walker method
161: . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
162: . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
163: . -snes_ksp_ew_gamma <gamma> - Sets gamma
164: . -snes_ksp_ew_alpha <alpha> - Sets alpha
165: . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2
166: - -snes_ksp_ew_threshold <threshold> - Sets threshold
168: Notes:
169: To see all options, run your program with the -help option or consult
170: the users manual.
172: Level: beginner
174: .keywords: SNES, nonlinear, set, options, database
176: .seealso: SNESSetOptionsPrefix()
177: @*/
178: int SNESSetFromOptions(SNES snes)
179: {
180: SLES sles;
181: SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
182: PetscTruth flg;
183: int ierr, i;
184: char *deft,type[256];
189: PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");
190: if (snes->type_name) {
191: deft = snes->type_name;
192: } else {
193: deft = SNESLS;
194: }
196: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
197: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
198: if (flg) {
199: SNESSetType(snes,type);
200: } else if (!snes->type_name) {
201: SNESSetType(snes,deft);
202: }
203: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
205: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
206: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->atol,&snes->atol,0);
208: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
209: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
210: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
211: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
213: PetscOptionsName("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetParametersEW",&snes->ksp_ewconv);
215: PetscOptionsInt("-snes_ksp_ew_version","Version 1 or 2","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);
216: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
217: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
218: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);
219: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);
220: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);
221: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);
223: PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);
224: if (flg) {snes->converged = 0;}
225: PetscOptionsName("-snes_cancelmonitors","Remove all monitors","SNESClearMonitor",&flg);
226: if (flg) {SNESClearMonitor(snes);}
227: PetscOptionsName("-snes_monitor","Monitor norm of function","SNESDefaultMonitor",&flg);
228: if (flg) {SNESSetMonitor(snes,SNESDefaultMonitor,0,0);}
229: PetscOptionsName("-snes_ratiomonitor","Monitor norm of function","SNESSetRatioMonitor",&flg);
230: if (flg) {SNESSetRatioMonitor(snes);}
231: PetscOptionsName("-snes_smonitor","Monitor norm of function (fewer digits)","SNESDefaultSMonitor",&flg);
232: if (flg) {SNESSetMonitor(snes,SNESDefaultSMonitor,0,0);}
233: PetscOptionsName("-snes_vecmonitor","Plot solution at each iteration","SNESVecViewMonitor",&flg);
234: if (flg) {SNESSetMonitor(snes,SNESVecViewMonitor,0,0);}
235: PetscOptionsName("-snes_vecmonitor_update","Plot correction at each iteration","SNESVecViewUpdateMonitor",&flg);
236: if (flg) {SNESSetMonitor(snes,SNESVecViewUpdateMonitor,0,0);}
237: PetscOptionsName("-snes_vecmonitor_residual","Plot residual at each iteration","SNESVecViewResidualMonitor",&flg);
238: if (flg) {SNESSetMonitor(snes,SNESVecViewResidualMonitor,0,0);}
239: PetscOptionsName("-snes_xmonitor","Plot function norm at each iteration","SNESLGMonitor",&flg);
240: if (flg) {SNESSetMonitor(snes,SNESLGMonitor,PETSC_NULL,PETSC_NULL);}
242: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
243: if (flg) {
244: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
245: PetscLogInfo(snes,"SNESSetFromOptions: Setting default finite difference Jacobian matrixn");
246: }
248: for(i = 0; i < numberofsetfromoptions; i++) {
249: (*othersetfromoptions[i])(snes);
250: }
252: if (snes->setfromoptions) {
253: (*snes->setfromoptions)(snes);
254: }
256: PetscOptionsEnd();
258: SNESGetSLES(snes,&sles);
259: SLESSetFromOptions(sles);
261: return(0);
262: }
265: /*@
266: SNESSetApplicationContext - Sets the optional user-defined context for
267: the nonlinear solvers.
269: Collective on SNES
271: Input Parameters:
272: + snes - the SNES context
273: - usrP - optional user context
275: Level: intermediate
277: .keywords: SNES, nonlinear, set, application, context
279: .seealso: SNESGetApplicationContext()
280: @*/
281: int SNESSetApplicationContext(SNES snes,void *usrP)
282: {
285: snes->user = usrP;
286: return(0);
287: }
289: /*@C
290: SNESGetApplicationContext - Gets the user-defined context for the
291: nonlinear solvers.
293: Not Collective
295: Input Parameter:
296: . snes - SNES context
298: Output Parameter:
299: . usrP - user context
301: Level: intermediate
303: .keywords: SNES, nonlinear, get, application, context
305: .seealso: SNESSetApplicationContext()
306: @*/
307: int SNESGetApplicationContext(SNES snes,void **usrP)
308: {
311: *usrP = snes->user;
312: return(0);
313: }
315: /*@
316: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
317: at this time.
319: Not Collective
321: Input Parameter:
322: . snes - SNES context
324: Output Parameter:
325: . iter - iteration number
327: Notes:
328: For example, during the computation of iteration 2 this would return 1.
330: This is useful for using lagged Jacobians (where one does not recompute the
331: Jacobian at each SNES iteration). For example, the code
332: .vb
333: SNESGetIterationNumber(snes,&it);
334: if (!(it % 2)) {
335: [compute Jacobian here]
336: }
337: .ve
338: can be used in your ComputeJacobian() function to cause the Jacobian to be
339: recomputed every second SNES iteration.
341: Level: intermediate
343: .keywords: SNES, nonlinear, get, iteration, number
344: @*/
345: int SNESGetIterationNumber(SNES snes,int* iter)
346: {
350: *iter = snes->iter;
351: return(0);
352: }
354: /*@
355: SNESGetFunctionNorm - Gets the norm of the current function that was set
356: with SNESSSetFunction().
358: Collective on SNES
360: Input Parameter:
361: . snes - SNES context
363: Output Parameter:
364: . fnorm - 2-norm of function
366: Level: intermediate
368: .keywords: SNES, nonlinear, get, function, norm
370: .seealso: SNESGetFunction()
371: @*/
372: int SNESGetFunctionNorm(SNES snes,PetscScalar *fnorm)
373: {
377: *fnorm = snes->norm;
378: return(0);
379: }
381: /*@
382: SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
383: attempted by the nonlinear solver.
385: Not Collective
387: Input Parameter:
388: . snes - SNES context
390: Output Parameter:
391: . nfails - number of unsuccessful steps attempted
393: Notes:
394: This counter is reset to zero for each successive call to SNESSolve().
396: Level: intermediate
398: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
399: @*/
400: int SNESGetNumberUnsuccessfulSteps(SNES snes,int* nfails)
401: {
405: *nfails = snes->numFailures;
406: return(0);
407: }
409: /*@
410: SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps
411: attempted by the nonlinear solver before it gives up.
413: Not Collective
415: Input Parameters:
416: + snes - SNES context
417: - maxFails - maximum of unsuccessful steps
419: Level: intermediate
421: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
422: @*/
423: int SNESSetMaximumUnsuccessfulSteps(SNES snes, int maxFails)
424: {
427: snes->maxFailures = maxFails;
428: return(0);
429: }
431: /*@
432: SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps
433: attempted by the nonlinear solver before it gives up.
435: Not Collective
437: Input Parameter:
438: . snes - SNES context
440: Output Parameter:
441: . maxFails - maximum of unsuccessful steps
443: Level: intermediate
445: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
446: @*/
447: int SNESGetMaximumUnsuccessfulSteps(SNES snes, int *maxFails)
448: {
452: *maxFails = snes->maxFailures;
453: return(0);
454: }
456: /*@
457: SNESGetNumberLinearIterations - Gets the total number of linear iterations
458: used by the nonlinear solver.
460: Not Collective
462: Input Parameter:
463: . snes - SNES context
465: Output Parameter:
466: . lits - number of linear iterations
468: Notes:
469: This counter is reset to zero for each successive call to SNESSolve().
471: Level: intermediate
473: .keywords: SNES, nonlinear, get, number, linear, iterations
474: @*/
475: int SNESGetNumberLinearIterations(SNES snes,int* lits)
476: {
480: *lits = snes->linear_its;
481: return(0);
482: }
484: /*@C
485: SNESGetSLES - Returns the SLES context for a SNES solver.
487: Not Collective, but if SNES object is parallel, then SLES object is parallel
489: Input Parameter:
490: . snes - the SNES context
492: Output Parameter:
493: . sles - the SLES context
495: Notes:
496: The user can then directly manipulate the SLES context to set various
497: options, etc. Likewise, the user can then extract and manipulate the
498: KSP and PC contexts as well.
500: Level: beginner
502: .keywords: SNES, nonlinear, get, SLES, context
504: .seealso: SLESGetPC(), SLESGetKSP()
505: @*/
506: int SNESGetSLES(SNES snes,SLES *sles)
507: {
510: *sles = snes->sles;
511: return(0);
512: }
514: static int SNESPublish_Petsc(PetscObject obj)
515: {
516: #if defined(PETSC_HAVE_AMS)
517: SNES v = (SNES) obj;
518: int ierr;
519: #endif
523: #if defined(PETSC_HAVE_AMS)
524: /* if it is already published then return */
525: if (v->amem >=0) return(0);
527: PetscObjectPublishBaseBegin(obj);
528: AMS_Memory_add_field((AMS_Memory)v->amem,"Iteration",&v->iter,1,AMS_INT,AMS_READ,
529: AMS_COMMON,AMS_REDUCT_UNDEF);
530: AMS_Memory_add_field((AMS_Memory)v->amem,"Residual",&v->norm,1,AMS_DOUBLE,AMS_READ,
531: AMS_COMMON,AMS_REDUCT_UNDEF);
532: PetscObjectPublishBaseEnd(obj);
533: #endif
534: return(0);
535: }
537: /* -----------------------------------------------------------*/
538: /*@C
539: SNESCreate - Creates a nonlinear solver context.
541: Collective on MPI_Comm
543: Input Parameters:
544: + comm - MPI communicator
546: Output Parameter:
547: . outsnes - the new SNES context
549: Options Database Keys:
550: + -snes_mf - Activates default matrix-free Jacobian-vector products,
551: and no preconditioning matrix
552: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
553: products, and a user-provided preconditioning matrix
554: as set by SNESSetJacobian()
555: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
557: Level: beginner
559: .keywords: SNES, nonlinear, create, context
561: .seealso: SNESSolve(), SNESDestroy(), SNES
562: @*/
563: int SNESCreate(MPI_Comm comm,SNES *outsnes)
564: {
565: int ierr;
566: SNES snes;
567: SNES_KSP_EW_ConvCtx *kctx;
571: *outsnes = PETSC_NULL;
572: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
573: SNESInitializePackage(PETSC_NULL);
574: #endif
576: PetscHeaderCreate(snes,_p_SNES,int,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
577: PetscLogObjectCreate(snes);
578: snes->bops->publish = SNESPublish_Petsc;
579: snes->max_its = 50;
580: snes->max_funcs = 10000;
581: snes->norm = 0.0;
582: snes->rtol = 1.e-8;
583: snes->ttol = 0.0;
584: snes->atol = 1.e-50;
585: snes->xtol = 1.e-8;
586: snes->deltatol = 1.e-12;
587: snes->nfuncs = 0;
588: snes->numFailures = 0;
589: snes->maxFailures = 1;
590: snes->linear_its = 0;
591: snes->numbermonitors = 0;
592: snes->data = 0;
593: snes->view = 0;
594: snes->setupcalled = 0;
595: snes->ksp_ewconv = PETSC_FALSE;
596: snes->vwork = 0;
597: snes->nwork = 0;
598: snes->conv_hist_len = 0;
599: snes->conv_hist_max = 0;
600: snes->conv_hist = PETSC_NULL;
601: snes->conv_hist_its = PETSC_NULL;
602: snes->conv_hist_reset = PETSC_TRUE;
603: snes->reason = SNES_CONVERGED_ITERATING;
605: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
606: PetscNew(SNES_KSP_EW_ConvCtx,&kctx);
607: PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));
608: snes->kspconvctx = (void*)kctx;
609: kctx->version = 2;
610: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
611: this was too large for some test cases */
612: kctx->rtol_last = 0;
613: kctx->rtol_max = .9;
614: kctx->gamma = 1.0;
615: kctx->alpha2 = .5*(1.0 + sqrt(5.0));
616: kctx->alpha = kctx->alpha2;
617: kctx->threshold = .1;
618: kctx->lresid_last = 0;
619: kctx->norm_last = 0;
621: SLESCreate(comm,&snes->sles);
622: PetscLogObjectParent(snes,snes->sles)
624: *outsnes = snes;
625: PetscPublishAll(snes);
626: return(0);
627: }
629: /* --------------------------------------------------------------- */
630: /*@C
631: SNESSetFunction - Sets the function evaluation routine and function
632: vector for use by the SNES routines in solving systems of nonlinear
633: equations.
635: Collective on SNES
637: Input Parameters:
638: + snes - the SNES context
639: . func - function evaluation routine
640: . r - vector to store function value
641: - ctx - [optional] user-defined context for private data for the
642: function evaluation routine (may be PETSC_NULL)
644: Calling sequence of func:
645: $ func (SNES snes,Vec x,Vec f,void *ctx);
647: . f - function vector
648: - ctx - optional user-defined function context
650: Notes:
651: The Newton-like methods typically solve linear systems of the form
652: $ f'(x) x = -f(x),
653: where f'(x) denotes the Jacobian matrix and f(x) is the function.
655: Level: beginner
657: .keywords: SNES, nonlinear, set, function
659: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
660: @*/
661: int SNESSetFunction(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*),void *ctx)
662: {
668: snes->computefunction = func;
669: snes->vec_func = snes->vec_func_always = r;
670: snes->funP = ctx;
671: return(0);
672: }
674: /*@
675: SNESComputeFunction - Calls the function that has been set with
676: SNESSetFunction().
678: Collective on SNES
680: Input Parameters:
681: + snes - the SNES context
682: - x - input vector
684: Output Parameter:
685: . y - function vector, as set by SNESSetFunction()
687: Notes:
688: SNESComputeFunction() is typically used within nonlinear solvers
689: implementations, so most users would not generally call this routine
690: themselves.
692: Level: developer
694: .keywords: SNES, nonlinear, compute, function
696: .seealso: SNESSetFunction(), SNESGetFunction()
697: @*/
698: int SNESComputeFunction(SNES snes,Vec x,Vec y)
699: {
700: int ierr;
709: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
710: PetscStackPush("SNES user function");
711: (*snes->computefunction)(snes,x,y,snes->funP);
712: PetscStackPop;
713: snes->nfuncs++;
714: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
715: return(0);
716: }
718: /*@
719: SNESComputeJacobian - Computes the Jacobian matrix that has been
720: set with SNESSetJacobian().
722: Collective on SNES and Mat
724: Input Parameters:
725: + snes - the SNES context
726: - x - input vector
728: Output Parameters:
729: + A - Jacobian matrix
730: . B - optional preconditioning matrix
731: - flag - flag indicating matrix structure
733: Notes:
734: Most users should not need to explicitly call this routine, as it
735: is used internally within the nonlinear solvers.
737: See SLESSetOperators() for important information about setting the
738: flag parameter.
740: Level: developer
742: .keywords: SNES, compute, Jacobian, matrix
744: .seealso: SNESSetJacobian(), SLESSetOperators()
745: @*/
746: int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
747: {
748: int ierr;
754: if (!snes->computejacobian) return(0);
755: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
756: *flg = DIFFERENT_NONZERO_PATTERN;
757: PetscStackPush("SNES user Jacobian function");
758: (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP);
759: PetscStackPop;
760: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
761: /* make sure user returned a correct Jacobian and preconditioner */
764: return(0);
765: }
767: /*@C
768: SNESSetJacobian - Sets the function to compute Jacobian as well as the
769: location to store the matrix.
771: Collective on SNES and Mat
773: Input Parameters:
774: + snes - the SNES context
775: . A - Jacobian matrix
776: . B - preconditioner matrix (usually same as the Jacobian)
777: . func - Jacobian evaluation routine
778: - ctx - [optional] user-defined context for private data for the
779: Jacobian evaluation routine (may be PETSC_NULL)
781: Calling sequence of func:
782: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
784: + x - input vector
785: . A - Jacobian matrix
786: . B - preconditioner matrix, usually the same as A
787: . flag - flag indicating information about the preconditioner matrix
788: structure (same as flag in SLESSetOperators())
789: - ctx - [optional] user-defined Jacobian context
791: Notes:
792: See SLESSetOperators() for important information about setting the flag
793: output parameter in the routine func(). Be sure to read this information!
795: The routine func() takes Mat * as the matrix arguments rather than Mat.
796: This allows the Jacobian evaluation routine to replace A and/or B with a
797: completely new new matrix structure (not just different matrix elements)
798: when appropriate, for instance, if the nonzero structure is changing
799: throughout the global iterations.
801: Level: beginner
803: .keywords: SNES, nonlinear, set, Jacobian, matrix
805: .seealso: SLESSetOperators(), SNESSetFunction()
806: @*/
807: int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
808: {
817: if (func) snes->computejacobian = func;
818: if (ctx) snes->jacP = ctx;
819: if (A) {
820: if (snes->jacobian) {MatDestroy(snes->jacobian);}
821: snes->jacobian = A;
822: ierr = PetscObjectReference((PetscObject)A);
823: }
824: if (B) {
825: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
826: snes->jacobian_pre = B;
827: ierr = PetscObjectReference((PetscObject)B);
828: }
829: return(0);
830: }
832: /*@C
833: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
834: provided context for evaluating the Jacobian.
836: Not Collective, but Mat object will be parallel if SNES object is
838: Input Parameter:
839: . snes - the nonlinear solver context
841: Output Parameters:
842: + A - location to stash Jacobian matrix (or PETSC_NULL)
843: . B - location to stash preconditioner matrix (or PETSC_NULL)
844: . ctx - location to stash Jacobian ctx (or PETSC_NULL)
845: - func - location to put Jacobian function (or PETSC_NULL)
847: Level: advanced
849: .seealso: SNESSetJacobian(), SNESComputeJacobian()
850: @*/
851: int SNESGetJacobian(SNES snes,Mat *A,Mat *B,void **ctx,int (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*))
852: {
855: if (A) *A = snes->jacobian;
856: if (B) *B = snes->jacobian_pre;
857: if (ctx) *ctx = snes->jacP;
858: if (func) *func = snes->computejacobian;
859: return(0);
860: }
862: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
863: extern int SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
865: /*@
866: SNESSetUp - Sets up the internal data structures for the later use
867: of a nonlinear solver.
869: Collective on SNES
871: Input Parameters:
872: + snes - the SNES context
873: - x - the solution vector
875: Notes:
876: For basic use of the SNES solvers the user need not explicitly call
877: SNESSetUp(), since these actions will automatically occur during
878: the call to SNESSolve(). However, if one wishes to control this
879: phase separately, SNESSetUp() should be called after SNESCreate()
880: and optional routines of the form SNESSetXXX(), but before SNESSolve().
882: Level: advanced
884: .keywords: SNES, nonlinear, setup
886: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
887: @*/
888: int SNESSetUp(SNES snes,Vec x)
889: {
890: int ierr;
891: PetscTruth flg, iseqtr;
897: snes->vec_sol = snes->vec_sol_always = x;
899: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
900: /*
901: This version replaces the user provided Jacobian matrix with a
902: matrix-free version but still employs the user-provided preconditioner matrix
903: */
904: if (flg) {
905: Mat J;
906: MatCreateSNESMF(snes,snes->vec_sol,&J);
907: MatSNESMFSetFromOptions(J);
908: PetscLogInfo(snes,"SNESSetUp: Setting default matrix-free operator routinesn");
909: SNESSetJacobian(snes,J,0,0,0);
910: MatDestroy(J);
911: }
913: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
914: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
915: if (flg) {
916: Mat J;
917: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
918: SNESSetJacobian(snes,J,0,0,0);
919: MatDestroy(J);
920: }
921: #endif
923: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
924: /*
925: This version replaces both the user-provided Jacobian and the user-
926: provided preconditioner matrix with the default matrix free version.
927: */
928: if (flg) {
929: Mat J;
930: SLES sles;
931: PC pc;
933: MatCreateSNESMF(snes,snes->vec_sol,&J);
934: MatSNESMFSetFromOptions(J);
935: PetscLogInfo(snes,"SNESSetUp: Setting default matrix-free operator and preconditioner routinesn");
936: SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);
937: MatDestroy(J);
939: /* force no preconditioner */
940: SNESGetSLES(snes,&sles);
941: SLESGetPC(sles,&pc);
942: PCSetType(pc,PCNONE);
943: }
945: if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
946: if (!snes->computefunction) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
947: if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first n or use -snes_mf option");
948: if (snes->vec_func == snes->vec_sol) {
949: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
950: }
952: /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
953: PetscTypeCompare((PetscObject)snes,SNESTR,&iseqtr);
954: if (snes->ksp_ewconv && !iseqtr) {
955: SLES sles; KSP ksp;
956: SNESGetSLES(snes,&sles);
957: SLESGetKSP(sles,&ksp);
958: KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,snes);
959: }
961: if (snes->setup) {(*snes->setup)(snes);}
962: snes->setupcalled = 1;
963: return(0);
964: }
966: /*@C
967: SNESDestroy - Destroys the nonlinear solver context that was created
968: with SNESCreate().
970: Collective on SNES
972: Input Parameter:
973: . snes - the SNES context
975: Level: beginner
977: .keywords: SNES, nonlinear, destroy
979: .seealso: SNESCreate(), SNESSolve()
980: @*/
981: int SNESDestroy(SNES snes)
982: {
983: int i,ierr;
987: if (--snes->refct > 0) return(0);
989: /* if memory was published with AMS then destroy it */
990: PetscObjectDepublish(snes);
992: if (snes->destroy) {(*(snes)->destroy)(snes);}
993: if (snes->kspconvctx) {PetscFree(snes->kspconvctx);}
994: if (snes->jacobian) {MatDestroy(snes->jacobian);}
995: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
996: SLESDestroy(snes->sles);
997: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
998: for (i=0; i<snes->numbermonitors; i++) {
999: if (snes->monitordestroy[i]) {
1000: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1001: }
1002: }
1003: PetscLogObjectDestroy((PetscObject)snes);
1004: PetscHeaderDestroy((PetscObject)snes);
1005: return(0);
1006: }
1008: /* ----------- Routines to set solver parameters ---------- */
1010: /*@
1011: SNESSetTolerances - Sets various parameters used in convergence tests.
1013: Collective on SNES
1015: Input Parameters:
1016: + snes - the SNES context
1017: . atol - absolute convergence tolerance
1018: . rtol - relative convergence tolerance
1019: . stol - convergence tolerance in terms of the norm
1020: of the change in the solution between steps
1021: . maxit - maximum number of iterations
1022: - maxf - maximum number of function evaluations
1024: Options Database Keys:
1025: + -snes_atol <atol> - Sets atol
1026: . -snes_rtol <rtol> - Sets rtol
1027: . -snes_stol <stol> - Sets stol
1028: . -snes_max_it <maxit> - Sets maxit
1029: - -snes_max_funcs <maxf> - Sets maxf
1031: Notes:
1032: The default maximum number of iterations is 50.
1033: The default maximum number of function evaluations is 1000.
1035: Level: intermediate
1037: .keywords: SNES, nonlinear, set, convergence, tolerances
1039: .seealso: SNESSetTrustRegionTolerance(), SNESSetMinimizationFunctionTolerance()
1040: @*/
1041: int SNESSetTolerances(SNES snes,PetscReal atol,PetscReal rtol,PetscReal stol,int maxit,int maxf)
1042: {
1045: if (atol != PETSC_DEFAULT) snes->atol = atol;
1046: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1047: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1048: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1049: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1050: return(0);
1051: }
1053: /*@
1054: SNESGetTolerances - Gets various parameters used in convergence tests.
1056: Not Collective
1058: Input Parameters:
1059: + snes - the SNES context
1060: . atol - absolute convergence tolerance
1061: . rtol - relative convergence tolerance
1062: . stol - convergence tolerance in terms of the norm
1063: of the change in the solution between steps
1064: . maxit - maximum number of iterations
1065: - maxf - maximum number of function evaluations
1067: Notes:
1068: The user can specify PETSC_NULL for any parameter that is not needed.
1070: Level: intermediate
1072: .keywords: SNES, nonlinear, get, convergence, tolerances
1074: .seealso: SNESSetTolerances()
1075: @*/
1076: int SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,int *maxit,int *maxf)
1077: {
1080: if (atol) *atol = snes->atol;
1081: if (rtol) *rtol = snes->rtol;
1082: if (stol) *stol = snes->xtol;
1083: if (maxit) *maxit = snes->max_its;
1084: if (maxf) *maxf = snes->max_funcs;
1085: return(0);
1086: }
1088: /*@
1089: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1091: Collective on SNES
1093: Input Parameters:
1094: + snes - the SNES context
1095: - tol - tolerance
1096:
1097: Options Database Key:
1098: . -snes_trtol <tol> - Sets tol
1100: Level: intermediate
1102: .keywords: SNES, nonlinear, set, trust region, tolerance
1104: .seealso: SNESSetTolerances(), SNESSetMinimizationFunctionTolerance()
1105: @*/
1106: int SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1107: {
1110: snes->deltatol = tol;
1111: return(0);
1112: }
1114: /*
1115: Duplicate the lg monitors for SNES from KSP; for some reason with
1116: dynamic libraries things don't work under Sun4 if we just use
1117: macros instead of functions
1118: */
1119: int SNESLGMonitor(SNES snes,int it,PetscReal norm,void *ctx)
1120: {
1125: KSPLGMonitor((KSP)snes,it,norm,ctx);
1126: return(0);
1127: }
1129: int SNESLGMonitorCreate(char *host,char *label,int x,int y,int m,int n,PetscDrawLG *draw)
1130: {
1134: KSPLGMonitorCreate(host,label,x,y,m,n,draw);
1135: return(0);
1136: }
1138: int SNESLGMonitorDestroy(PetscDrawLG draw)
1139: {
1143: KSPLGMonitorDestroy(draw);
1144: return(0);
1145: }
1147: /* ------------ Routines to set performance monitoring options ----------- */
1149: /*@C
1150: SNESSetMonitor - Sets an ADDITIONAL function that is to be used at every
1151: iteration of the nonlinear solver to display the iteration's
1152: progress.
1154: Collective on SNES
1156: Input Parameters:
1157: + snes - the SNES context
1158: . func - monitoring routine
1159: . mctx - [optional] user-defined context for private data for the
1160: monitor routine (use PETSC_NULL if no context is desitre)
1161: - monitordestroy - [optional] routine that frees monitor context
1162: (may be PETSC_NULL)
1164: Calling sequence of func:
1165: $ int func(SNES snes,int its, PetscReal norm,void *mctx)
1167: + snes - the SNES context
1168: . its - iteration number
1169: . norm - 2-norm function value (may be estimated)
1170: - mctx - [optional] monitoring context
1172: Options Database Keys:
1173: + -snes_monitor - sets SNESDefaultMonitor()
1174: . -snes_xmonitor - sets line graph monitor,
1175: uses SNESLGMonitorCreate()
1176: _ -snes_cancelmonitors - cancels all monitors that have
1177: been hardwired into a code by
1178: calls to SNESSetMonitor(), but
1179: does not cancel those set via
1180: the options database.
1182: Notes:
1183: Several different monitoring routines may be set by calling
1184: SNESSetMonitor() multiple times; all will be called in the
1185: order in which they were set.
1187: Level: intermediate
1189: .keywords: SNES, nonlinear, set, monitor
1191: .seealso: SNESDefaultMonitor(), SNESClearMonitor()
1192: @*/
1193: int SNESSetMonitor(SNES snes,int (*func)(SNES,int,PetscReal,void*),void *mctx,int (*monitordestroy)(void *))
1194: {
1197: if (snes->numbermonitors >= MAXSNESMONITORS) {
1198: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1199: }
1201: snes->monitor[snes->numbermonitors] = func;
1202: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1203: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1204: return(0);
1205: }
1207: /*@C
1208: SNESClearMonitor - Clears all the monitor functions for a SNES object.
1210: Collective on SNES
1212: Input Parameters:
1213: . snes - the SNES context
1215: Options Database:
1216: . -snes_cancelmonitors - cancels all monitors that have been hardwired
1217: into a code by calls to SNESSetMonitor(), but does not cancel those
1218: set via the options database
1220: Notes:
1221: There is no way to clear one specific monitor from a SNES object.
1223: Level: intermediate
1225: .keywords: SNES, nonlinear, set, monitor
1227: .seealso: SNESDefaultMonitor(), SNESSetMonitor()
1228: @*/
1229: int SNESClearMonitor(SNES snes)
1230: {
1233: snes->numbermonitors = 0;
1234: return(0);
1235: }
1237: /*@C
1238: SNESSetConvergenceTest - Sets the function that is to be used
1239: to test for convergence of the nonlinear iterative solution.
1241: Collective on SNES
1243: Input Parameters:
1244: + snes - the SNES context
1245: . func - routine to test for convergence
1246: - cctx - [optional] context for private data for the convergence routine
1247: (may be PETSC_NULL)
1249: Calling sequence of func:
1250: $ int func (SNES snes,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1252: + snes - the SNES context
1253: . cctx - [optional] convergence context
1254: . reason - reason for convergence/divergence
1255: . xnorm - 2-norm of current iterate
1256: . gnorm - 2-norm of current step
1257: - f - 2-norm of function
1259: Level: advanced
1261: .keywords: SNES, nonlinear, set, convergence, test
1263: .seealso: SNESConverged_LS(), SNESConverged_TR()
1264: @*/
1265: int SNESSetConvergenceTest(SNES snes,int (*func)(SNES,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1266: {
1269: (snes)->converged = func;
1270: (snes)->cnvP = cctx;
1271: return(0);
1272: }
1274: /*@C
1275: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1277: Not Collective
1279: Input Parameter:
1280: . snes - the SNES context
1282: Output Parameter:
1283: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1284: manual pages for the individual convergence tests for complete lists
1286: Level: intermediate
1288: Notes: Can only be called after the call the SNESSolve() is complete.
1290: .keywords: SNES, nonlinear, set, convergence, test
1292: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1293: @*/
1294: int SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1295: {
1298: *reason = snes->reason;
1299: return(0);
1300: }
1302: /*@
1303: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1305: Collective on SNES
1307: Input Parameters:
1308: + snes - iterative context obtained from SNESCreate()
1309: . a - array to hold history
1310: . its - integer array holds the number of linear iterations for each solve.
1311: . na - size of a and its
1312: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1313: else it continues storing new values for new nonlinear solves after the old ones
1315: Notes:
1316: If set, this array will contain the function norms computed
1317: at each step.
1319: This routine is useful, e.g., when running a code for purposes
1320: of accurate performance monitoring, when no I/O should be done
1321: during the section of code that is being timed.
1323: Level: intermediate
1325: .keywords: SNES, set, convergence, history
1327: .seealso: SNESGetConvergenceHistory()
1329: @*/
1330: int SNESSetConvergenceHistory(SNES snes,PetscReal *a,int *its,int na,PetscTruth reset)
1331: {
1335: snes->conv_hist = a;
1336: snes->conv_hist_its = its;
1337: snes->conv_hist_max = na;
1338: snes->conv_hist_reset = reset;
1339: return(0);
1340: }
1342: /*@C
1343: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1345: Collective on SNES
1347: Input Parameter:
1348: . snes - iterative context obtained from SNESCreate()
1350: Output Parameters:
1351: . a - array to hold history
1352: . its - integer array holds the number of linear iterations (or
1353: negative if not converged) for each solve.
1354: - na - size of a and its
1356: Notes:
1357: The calling sequence for this routine in Fortran is
1358: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1360: This routine is useful, e.g., when running a code for purposes
1361: of accurate performance monitoring, when no I/O should be done
1362: during the section of code that is being timed.
1364: Level: intermediate
1366: .keywords: SNES, get, convergence, history
1368: .seealso: SNESSetConvergencHistory()
1370: @*/
1371: int SNESGetConvergenceHistory(SNES snes,PetscReal **a,int **its,int *na)
1372: {
1375: if (a) *a = snes->conv_hist;
1376: if (its) *its = snes->conv_hist_its;
1377: if (na) *na = snes->conv_hist_len;
1378: return(0);
1379: }
1381: /*@
1382: SNESSetRhsBC - Sets the function which applies boundary conditions
1383: to the Rhs of each system.
1385: Collective on SNES
1387: Input Parameters:
1388: . snes - The nonlinear solver context
1389: . func - The function
1391: Calling sequence of func:
1392: . func (SNES snes, Vec rhs, void *ctx);
1394: . rhs - The current rhs vector
1395: . ctx - The user-context
1397: Level: intermediate
1399: .keywords: SNES, Rhs, boundary conditions
1400: .seealso SNESDefaultRhsBC(), SNESSetSolutionBC(), SNESSetUpdate()
1401: @*/
1402: int SNESSetRhsBC(SNES snes, int (*func)(SNES, Vec, void *))
1403: {
1406: snes->applyrhsbc = func;
1407: return(0);
1408: }
1410: /*@
1411: SNESDefaultRhsBC - The default boundary condition function which does nothing.
1413: Not collective
1415: Input Parameters:
1416: . snes - The nonlinear solver context
1417: . rhs - The Rhs
1418: . ctx - The user-context
1420: Level: beginner
1422: .keywords: SNES, Rhs, boundary conditions
1423: .seealso SNESSetRhsBC(), SNESDefaultSolutionBC(), SNESDefaultUpdate()
1424: @*/
1425: int SNESDefaultRhsBC(SNES snes, Vec rhs, void *ctx)
1426: {
1428: return(0);
1429: }
1431: /*@
1432: SNESSetSolutionBC - Sets the function which applies boundary conditions
1433: to the solution of each system.
1435: Collective on SNES
1437: Input Parameters:
1438: . snes - The nonlinear solver context
1439: . func - The function
1441: Calling sequence of func:
1442: . func (TS ts, Vec rsol, void *ctx);
1444: . sol - The current solution vector
1445: . ctx - The user-context
1447: Level: intermediate
1449: .keywords: SNES, solution, boundary conditions
1450: .seealso SNESDefaultSolutionBC(), SNESSetRhsBC(), SNESSetUpdate()
1451: @*/
1452: int SNESSetSolutionBC(SNES snes, int (*func)(SNES, Vec, void *))
1453: {
1456: snes->applysolbc = func;
1457: return(0);
1458: }
1460: /*@
1461: SNESDefaultSolutionBC - The default boundary condition function which does nothing.
1463: Not collective
1465: Input Parameters:
1466: . snes - The nonlinear solver context
1467: . sol - The solution
1468: . ctx - The user-context
1470: Level: beginner
1472: .keywords: SNES, solution, boundary conditions
1473: .seealso SNESSetSolutionBC(), SNESDefaultRhsBC(), SNESDefaultUpdate()
1474: @*/
1475: int SNESDefaultSolutionBC(SNES snes, Vec sol, void *ctx)
1476: {
1478: return(0);
1479: }
1481: /*@
1482: SNESSetUpdate - Sets the general-purpose update function called
1483: at the beginning of every step of the iteration.
1485: Collective on SNES
1487: Input Parameters:
1488: . snes - The nonlinear solver context
1489: . func - The function
1491: Calling sequence of func:
1492: . func (TS ts, int step);
1494: . step - The current step of the iteration
1496: Level: intermediate
1498: .keywords: SNES, update
1499: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1500: @*/
1501: int SNESSetUpdate(SNES snes, int (*func)(SNES, int))
1502: {
1505: snes->update = func;
1506: return(0);
1507: }
1509: /*@
1510: SNESDefaultUpdate - The default update function which does nothing.
1512: Not collective
1514: Input Parameters:
1515: . snes - The nonlinear solver context
1516: . step - The current step of the iteration
1518: Level: intermediate
1520: .keywords: SNES, update
1521: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultSolutionBC()
1522: @*/
1523: int SNESDefaultUpdate(SNES snes, int step)
1524: {
1526: return(0);
1527: }
1529: /*
1530: SNESScaleStep_Private - Scales a step so that its length is less than the
1531: positive parameter delta.
1533: Input Parameters:
1534: + snes - the SNES context
1535: . y - approximate solution of linear system
1536: . fnorm - 2-norm of current function
1537: - delta - trust region size
1539: Output Parameters:
1540: + gpnorm - predicted function norm at the new point, assuming local
1541: linearization. The value is zero if the step lies within the trust
1542: region, and exceeds zero otherwise.
1543: - ynorm - 2-norm of the step
1545: Note:
1546: For non-trust region methods such as SNESLS, the parameter delta
1547: is set to be the maximum allowable step size.
1549: .keywords: SNES, nonlinear, scale, step
1550: */
1551: int SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1552: {
1553: PetscReal nrm;
1554: PetscScalar cnorm;
1555: int ierr;
1562: VecNorm(y,NORM_2,&nrm);
1563: if (nrm > *delta) {
1564: nrm = *delta/nrm;
1565: *gpnorm = (1.0 - nrm)*(*fnorm);
1566: cnorm = nrm;
1567: VecScale(&cnorm,y);
1568: *ynorm = *delta;
1569: } else {
1570: *gpnorm = 0.0;
1571: *ynorm = nrm;
1572: }
1573: return(0);
1574: }
1576: /*@
1577: SNESSolve - Solves a nonlinear system. Call SNESSolve after calling
1578: SNESCreate() and optional routines of the form SNESSetXXX().
1580: Collective on SNES
1582: Input Parameters:
1583: + snes - the SNES context
1584: - x - the solution vector
1586: Output Parameter:
1587: . its - number of iterations until termination
1589: Notes:
1590: The user should initialize the vector,x, with the initial guess
1591: for the nonlinear solve prior to calling SNESSolve. In particular,
1592: to employ an initial guess of zero, the user should explicitly set
1593: this vector to zero by calling VecSet().
1595: Level: beginner
1597: .keywords: SNES, nonlinear, solve
1599: .seealso: SNESCreate(), SNESDestroy()
1600: @*/
1601: int SNESSolve(SNES snes,Vec x,int *its)
1602: {
1603: int ierr;
1604: PetscTruth flg;
1611: if (!snes->solve) SETERRQ(1,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1613: if (!snes->setupcalled) {SNESSetUp(snes,x);}
1614: else {snes->vec_sol = snes->vec_sol_always = x;}
1615: if (snes->conv_hist_reset == PETSC_TRUE) snes->conv_hist_len = 0;
1616: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
1617: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1618: (*(snes)->solve)(snes,its);
1619: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
1620: PetscOptionsHasName(snes->prefix,"-snes_view",&flg);
1621: if (flg && !PetscPreLoadingOn) { SNESView(snes,PETSC_VIEWER_STDOUT_WORLD); }
1622: return(0);
1623: }
1625: /* --------- Internal routines for SNES Package --------- */
1627: /*@C
1628: SNESSetType - Sets the method for the nonlinear solver.
1630: Collective on SNES
1632: Input Parameters:
1633: + snes - the SNES context
1634: - type - a known method
1636: Options Database Key:
1637: . -snes_type <type> - Sets the method; use -help for a list
1638: of available methods (for instance, ls or tr)
1640: Notes:
1641: See "petsc/include/petscsnes.h" for available methods (for instance)
1642: + SNESLS - Newton's method with line search
1643: (systems of nonlinear equations)
1644: . SNESTR - Newton's method with trust region
1645: (systems of nonlinear equations)
1647: Normally, it is best to use the SNESSetFromOptions() command and then
1648: set the SNES solver type from the options database rather than by using
1649: this routine. Using the options database provides the user with
1650: maximum flexibility in evaluating the many nonlinear solvers.
1651: The SNESSetType() routine is provided for those situations where it
1652: is necessary to set the nonlinear solver independently of the command
1653: line or options database. This might be the case, for example, when
1654: the choice of solver changes during the execution of the program,
1655: and the user's application is taking responsibility for choosing the
1656: appropriate method.
1658: Level: intermediate
1660: .keywords: SNES, set, type
1662: .seealso: SNESType, SNESCreate()
1664: @*/
1665: int SNESSetType(SNES snes,SNESType type)
1666: {
1667: int ierr,(*r)(SNES);
1668: PetscTruth match;
1674: PetscTypeCompare((PetscObject)snes,type,&match);
1675: if (match) return(0);
1677: if (snes->setupcalled) {
1678: ierr = (*(snes)->destroy)(snes);
1679: snes->data = 0;
1680: }
1682: /* Get the function pointers for the iterative method requested */
1683: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
1685: PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);
1687: if (!r) SETERRQ1(1,"Unable to find requested SNES type %s",type);
1689: if (snes->data) {PetscFree(snes->data);}
1690: snes->data = 0;
1691: (*r)(snes);
1692: PetscObjectChangeTypeName((PetscObject)snes,type);
1694: return(0);
1695: }
1698: /* --------------------------------------------------------------------- */
1699: /*@C
1700: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1701: registered by SNESRegisterDynamic().
1703: Not Collective
1705: Level: advanced
1707: .keywords: SNES, nonlinear, register, destroy
1709: .seealso: SNESRegisterAll(), SNESRegisterAll()
1710: @*/
1711: int SNESRegisterDestroy(void)
1712: {
1716: if (SNESList) {
1717: PetscFListDestroy(&SNESList);
1718: SNESList = 0;
1719: }
1720: SNESRegisterAllCalled = PETSC_FALSE;
1721: return(0);
1722: }
1724: /*@C
1725: SNESGetType - Gets the SNES method type and name (as a string).
1727: Not Collective
1729: Input Parameter:
1730: . snes - nonlinear solver context
1732: Output Parameter:
1733: . type - SNES method (a character string)
1735: Level: intermediate
1737: .keywords: SNES, nonlinear, get, type, name
1738: @*/
1739: int SNESGetType(SNES snes,SNESType *type)
1740: {
1743: *type = snes->type_name;
1744: return(0);
1745: }
1747: /*@C
1748: SNESGetSolution - Returns the vector where the approximate solution is
1749: stored.
1751: Not Collective, but Vec is parallel if SNES is parallel
1753: Input Parameter:
1754: . snes - the SNES context
1756: Output Parameter:
1757: . x - the solution
1759: Level: advanced
1761: .keywords: SNES, nonlinear, get, solution
1763: .seealso: SNESGetFunction(), SNESGetSolutionUpdate()
1764: @*/
1765: int SNESGetSolution(SNES snes,Vec *x)
1766: {
1769: *x = snes->vec_sol_always;
1770: return(0);
1771: }
1773: /*@C
1774: SNESGetSolutionUpdate - Returns the vector where the solution update is
1775: stored.
1777: Not Collective, but Vec is parallel if SNES is parallel
1779: Input Parameter:
1780: . snes - the SNES context
1782: Output Parameter:
1783: . x - the solution update
1785: Level: advanced
1787: .keywords: SNES, nonlinear, get, solution, update
1789: .seealso: SNESGetSolution(), SNESGetFunction
1790: @*/
1791: int SNESGetSolutionUpdate(SNES snes,Vec *x)
1792: {
1795: *x = snes->vec_sol_update_always;
1796: return(0);
1797: }
1799: /*@C
1800: SNESGetFunction - Returns the vector where the function is stored.
1802: Not Collective, but Vec is parallel if SNES is parallel
1804: Input Parameter:
1805: . snes - the SNES context
1807: Output Parameter:
1808: + r - the function (or PETSC_NULL)
1809: . ctx - the function context (or PETSC_NULL)
1810: - func - the function (or PETSC_NULL)
1812: Level: advanced
1814: .keywords: SNES, nonlinear, get, function
1816: .seealso: SNESSetFunction(), SNESGetSolution()
1817: @*/
1818: int SNESGetFunction(SNES snes,Vec *r,void **ctx,int (**func)(SNES,Vec,Vec,void*))
1819: {
1822: if (r) *r = snes->vec_func_always;
1823: if (ctx) *ctx = snes->funP;
1824: if (func) *func = snes->computefunction;
1825: return(0);
1826: }
1828: /*@C
1829: SNESSetOptionsPrefix - Sets the prefix used for searching for all
1830: SNES options in the database.
1832: Collective on SNES
1834: Input Parameter:
1835: + snes - the SNES context
1836: - prefix - the prefix to prepend to all option names
1838: Notes:
1839: A hyphen (-) must NOT be given at the beginning of the prefix name.
1840: The first character of all runtime options is AUTOMATICALLY the hyphen.
1842: Level: advanced
1844: .keywords: SNES, set, options, prefix, database
1846: .seealso: SNESSetFromOptions()
1847: @*/
1848: int SNESSetOptionsPrefix(SNES snes,char *prefix)
1849: {
1854: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
1855: SLESSetOptionsPrefix(snes->sles,prefix);
1856: return(0);
1857: }
1859: /*@C
1860: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
1861: SNES options in the database.
1863: Collective on SNES
1865: Input Parameters:
1866: + snes - the SNES context
1867: - prefix - the prefix to prepend to all option names
1869: Notes:
1870: A hyphen (-) must NOT be given at the beginning of the prefix name.
1871: The first character of all runtime options is AUTOMATICALLY the hyphen.
1873: Level: advanced
1875: .keywords: SNES, append, options, prefix, database
1877: .seealso: SNESGetOptionsPrefix()
1878: @*/
1879: int SNESAppendOptionsPrefix(SNES snes,char *prefix)
1880: {
1882:
1885: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
1886: SLESAppendOptionsPrefix(snes->sles,prefix);
1887: return(0);
1888: }
1890: /*@C
1891: SNESGetOptionsPrefix - Sets the prefix used for searching for all
1892: SNES options in the database.
1894: Not Collective
1896: Input Parameter:
1897: . snes - the SNES context
1899: Output Parameter:
1900: . prefix - pointer to the prefix string used
1902: Notes: On the fortran side, the user should pass in a string 'prifix' of
1903: sufficient length to hold the prefix.
1905: Level: advanced
1907: .keywords: SNES, get, options, prefix, database
1909: .seealso: SNESAppendOptionsPrefix()
1910: @*/
1911: int SNESGetOptionsPrefix(SNES snes,char **prefix)
1912: {
1917: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
1918: return(0);
1919: }
1921: /*MC
1922: SNESRegisterDynamic - Adds a method to the nonlinear solver package.
1924: Synopsis:
1925: int SNESRegisterDynamic(char *name_solver,char *path,char *name_create,int (*routine_create)(SNES))
1927: Not collective
1929: Input Parameters:
1930: + name_solver - name of a new user-defined solver
1931: . path - path (either absolute or relative) the library containing this solver
1932: . name_create - name of routine to create method context
1933: - routine_create - routine to create method context
1935: Notes:
1936: SNESRegisterDynamic() may be called multiple times to add several user-defined solvers.
1938: If dynamic libraries are used, then the fourth input argument (routine_create)
1939: is ignored.
1941: Environmental variables such as ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, ${BOPT},
1942: and others of the form ${any_environmental_variable} occuring in pathname will be
1943: replaced with appropriate values.
1945: Sample usage:
1946: .vb
1947: SNESRegisterDynamic("my_solver",/home/username/my_lib/lib/libg/solaris/mylib.a,
1948: "MySolverCreate",MySolverCreate);
1949: .ve
1951: Then, your solver can be chosen with the procedural interface via
1952: $ SNESSetType(snes,"my_solver")
1953: or at runtime via the option
1954: $ -snes_type my_solver
1956: Level: advanced
1958: .keywords: SNES, nonlinear, register
1960: .seealso: SNESRegisterAll(), SNESRegisterDestroy()
1961: M*/
1963: int SNESRegister(char *sname,char *path,char *name,int (*function)(SNES))
1964: {
1965: char fullname[256];
1966: int ierr;
1969: PetscFListConcat(path,name,fullname);
1970: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
1971: return(0);
1972: }