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 = 0;
10: int 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: int SNESView(SNES snes,PetscViewer viewer)
44: {
45: SNES_KSP_EW_ConvCtx *kctx;
46: int ierr;
47: KSP ksp;
48: char *type;
49: PetscTruth isascii,isstring;
53: if (!viewer) viewer = PETSC_VIEWER_STDOUT_(snes->comm);
57: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
58: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
59: if (isascii) {
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->atol,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 int numberofsetfromoptions;
106: static int (*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: int SNESAddOptionsChecker(int (*snescheck)(SNES))
123: {
125: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
126: SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS);
127: }
129: othersetfromoptions[numberofsetfromoptions++] = snescheck;
130: return(0);
131: }
135: /*@
136: SNESSetFromOptions - Sets various SNES and KSP parameters from user options.
138: Collective on SNES
140: Input Parameter:
141: . snes - the SNES context
143: Options Database Keys:
144: + -snes_type <type> - ls, tr, umls, umtr, test
145: . -snes_stol - convergence tolerance in terms of the norm
146: of the change in the solution between steps
147: . -snes_atol <atol> - absolute tolerance of residual norm
148: . -snes_rtol <rtol> - relative decrease in tolerance norm from initial
149: . -snes_max_it <max_it> - maximum number of iterations
150: . -snes_max_funcs <max_funcs> - maximum number of function evaluations
151: . -snes_max_fail <max_fail> - maximum number of failures
152: . -snes_trtol <trtol> - trust region tolerance
153: . -snes_no_convergence_test - skip convergence test in nonlinear or minimization
154: solver; hence iterations will continue until max_it
155: or some other criterion is reached. Saves expense
156: of convergence test
157: . -snes_monitor - prints residual norm at each iteration
158: . -snes_vecmonitor - plots solution at each iteration
159: . -snes_vecmonitor_update - plots update to solution at each iteration
160: . -snes_xmonitor - plots residual norm at each iteration
161: . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
162: - -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
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: int SNESSetFromOptions(SNES snes)
185: {
186: KSP ksp;
187: SNES_KSP_EW_ConvCtx *kctx = (SNES_KSP_EW_ConvCtx *)snes->kspconvctx;
188: PetscTruth flg;
189: int ierr, i;
190: const char *deft;
191: char type[256];
196: PetscOptionsBegin(snes->comm,snes->prefix,"Nonlinear solver (SNES) options","SNES");
197: if (snes->type_name) {
198: deft = snes->type_name;
199: } else {
200: deft = SNESLS;
201: }
203: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
204: PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
205: if (flg) {
206: SNESSetType(snes,type);
207: } else if (!snes->type_name) {
208: SNESSetType(snes,deft);
209: }
210: PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);
212: PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
213: PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->atol,&snes->atol,0);
215: PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
216: PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
217: PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
218: PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);
220: PetscOptionsName("-snes_ksp_ew_conv","Use Eisentat-Walker linear system convergence test","SNES_KSP_SetParametersEW",&snes->ksp_ewconv);
222: PetscOptionsInt("-snes_ksp_ew_version","Version 1 or 2","SNES_KSP_SetParametersEW",kctx->version,&kctx->version,0);
223: PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNES_KSP_SetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
224: PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNES_KSP_SetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
225: PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNES_KSP_SetParametersEW",kctx->gamma,&kctx->gamma,0);
226: PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNES_KSP_SetParametersEW",kctx->alpha,&kctx->alpha,0);
227: PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNES_KSP_SetParametersEW",kctx->alpha2,&kctx->alpha2,0);
228: PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNES_KSP_SetParametersEW",kctx->threshold,&kctx->threshold,0);
230: PetscOptionsName("-snes_no_convergence_test","Don't test for convergence","None",&flg);
231: if (flg) {snes->converged = 0;}
232: PetscOptionsName("-snes_cancelmonitors","Remove all monitors","SNESClearMonitor",&flg);
233: if (flg) {SNESClearMonitor(snes);}
234: PetscOptionsName("-snes_monitor","Monitor norm of function","SNESDefaultMonitor",&flg);
235: if (flg) {SNESSetMonitor(snes,SNESDefaultMonitor,0,0);}
236: PetscOptionsName("-snes_ratiomonitor","Monitor norm of function","SNESSetRatioMonitor",&flg);
237: if (flg) {SNESSetRatioMonitor(snes);}
238: PetscOptionsName("-snes_smonitor","Monitor norm of function (fewer digits)","SNESDefaultSMonitor",&flg);
239: if (flg) {SNESSetMonitor(snes,SNESDefaultSMonitor,0,0);}
240: PetscOptionsName("-snes_vecmonitor","Plot solution at each iteration","SNESVecViewMonitor",&flg);
241: if (flg) {SNESSetMonitor(snes,SNESVecViewMonitor,0,0);}
242: PetscOptionsName("-snes_vecmonitor_update","Plot correction at each iteration","SNESVecViewUpdateMonitor",&flg);
243: if (flg) {SNESSetMonitor(snes,SNESVecViewUpdateMonitor,0,0);}
244: PetscOptionsName("-snes_vecmonitor_residual","Plot residual at each iteration","SNESVecViewResidualMonitor",&flg);
245: if (flg) {SNESSetMonitor(snes,SNESVecViewResidualMonitor,0,0);}
246: PetscOptionsName("-snes_xmonitor","Plot function norm at each iteration","SNESLGMonitor",&flg);
247: if (flg) {SNESSetMonitor(snes,SNESLGMonitor,PETSC_NULL,PETSC_NULL);}
249: PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
250: if (flg) {
251: SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
252: PetscLogInfo(snes,"SNESSetFromOptions: Setting default finite difference Jacobian matrix\n");
253: }
255: for(i = 0; i < numberofsetfromoptions; i++) {
256: (*othersetfromoptions[i])(snes);
257: }
259: if (snes->setfromoptions) {
260: (*snes->setfromoptions)(snes);
261: }
263: PetscOptionsEnd();
265: SNESGetKSP(snes,&ksp);
266: KSPSetFromOptions(ksp);
268: return(0);
269: }
274: /*@
275: SNESSetApplicationContext - Sets the optional user-defined context for
276: the nonlinear solvers.
278: Collective on SNES
280: Input Parameters:
281: + snes - the SNES context
282: - usrP - optional user context
284: Level: intermediate
286: .keywords: SNES, nonlinear, set, application, context
288: .seealso: SNESGetApplicationContext()
289: @*/
290: int SNESSetApplicationContext(SNES snes,void *usrP)
291: {
294: snes->user = usrP;
295: return(0);
296: }
300: /*@C
301: SNESGetApplicationContext - Gets the user-defined context for the
302: nonlinear solvers.
304: Not Collective
306: Input Parameter:
307: . snes - SNES context
309: Output Parameter:
310: . usrP - user context
312: Level: intermediate
314: .keywords: SNES, nonlinear, get, application, context
316: .seealso: SNESSetApplicationContext()
317: @*/
318: int SNESGetApplicationContext(SNES snes,void **usrP)
319: {
322: *usrP = snes->user;
323: return(0);
324: }
328: /*@
329: SNESGetIterationNumber - Gets the number of nonlinear iterations completed
330: at this time.
332: Not Collective
334: Input Parameter:
335: . snes - SNES context
337: Output Parameter:
338: . iter - iteration number
340: Notes:
341: For example, during the computation of iteration 2 this would return 1.
343: This is useful for using lagged Jacobians (where one does not recompute the
344: Jacobian at each SNES iteration). For example, the code
345: .vb
346: SNESGetIterationNumber(snes,&it);
347: if (!(it % 2)) {
348: [compute Jacobian here]
349: }
350: .ve
351: can be used in your ComputeJacobian() function to cause the Jacobian to be
352: recomputed every second SNES iteration.
354: Level: intermediate
356: .keywords: SNES, nonlinear, get, iteration, number
357: @*/
358: int SNESGetIterationNumber(SNES snes,int* iter)
359: {
363: *iter = snes->iter;
364: return(0);
365: }
369: /*@
370: SNESGetFunctionNorm - Gets the norm of the current function that was set
371: with SNESSSetFunction().
373: Collective on SNES
375: Input Parameter:
376: . snes - SNES context
378: Output Parameter:
379: . fnorm - 2-norm of function
381: Level: intermediate
383: .keywords: SNES, nonlinear, get, function, norm
385: .seealso: SNESGetFunction()
386: @*/
387: int SNESGetFunctionNorm(SNES snes,PetscScalar *fnorm)
388: {
392: *fnorm = snes->norm;
393: return(0);
394: }
398: /*@
399: SNESGetNumberUnsuccessfulSteps - Gets the number of unsuccessful steps
400: attempted by the nonlinear solver.
402: Not Collective
404: Input Parameter:
405: . snes - SNES context
407: Output Parameter:
408: . nfails - number of unsuccessful steps attempted
410: Notes:
411: This counter is reset to zero for each successive call to SNESSolve().
413: Level: intermediate
415: .keywords: SNES, nonlinear, get, number, unsuccessful, steps
416: @*/
417: int SNESGetNumberUnsuccessfulSteps(SNES snes,int* nfails)
418: {
422: *nfails = snes->numFailures;
423: return(0);
424: }
428: /*@
429: SNESSetMaximumUnsuccessfulSteps - Sets the maximum number of unsuccessful steps
430: attempted by the nonlinear solver before it gives up.
432: Not Collective
434: Input Parameters:
435: + snes - SNES context
436: - maxFails - maximum of unsuccessful steps
438: Level: intermediate
440: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps
441: @*/
442: int SNESSetMaximumUnsuccessfulSteps(SNES snes, int maxFails)
443: {
446: snes->maxFailures = maxFails;
447: return(0);
448: }
452: /*@
453: SNESGetMaximumUnsuccessfulSteps - Gets the maximum number of unsuccessful steps
454: attempted by the nonlinear solver before it gives up.
456: Not Collective
458: Input Parameter:
459: . snes - SNES context
461: Output Parameter:
462: . maxFails - maximum of unsuccessful steps
464: Level: intermediate
466: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps
467: @*/
468: int SNESGetMaximumUnsuccessfulSteps(SNES snes, int *maxFails)
469: {
473: *maxFails = snes->maxFailures;
474: return(0);
475: }
479: /*@
480: SNESGetNumberLinearIterations - Gets the total number of linear iterations
481: used by the nonlinear solver.
483: Not Collective
485: Input Parameter:
486: . snes - SNES context
488: Output Parameter:
489: . lits - number of linear iterations
491: Notes:
492: This counter is reset to zero for each successive call to SNESSolve().
494: Level: intermediate
496: .keywords: SNES, nonlinear, get, number, linear, iterations
497: @*/
498: int SNESGetNumberLinearIterations(SNES snes,int* lits)
499: {
503: *lits = snes->linear_its;
504: return(0);
505: }
509: /*@C
510: SNESGetKSP - Returns the KSP context for a SNES solver.
512: Not Collective, but if SNES object is parallel, then KSP object is parallel
514: Input Parameter:
515: . snes - the SNES context
517: Output Parameter:
518: . ksp - the KSP context
520: Notes:
521: The user can then directly manipulate the KSP context to set various
522: options, etc. Likewise, the user can then extract and manipulate the
523: KSP and PC contexts as well.
525: Level: beginner
527: .keywords: SNES, nonlinear, get, KSP, context
529: .seealso: KSPGetPC()
530: @*/
531: int SNESGetKSP(SNES snes,KSP *ksp)
532: {
536: *ksp = snes->ksp;
537: return(0);
538: }
542: static int SNESPublish_Petsc(PetscObject obj)
543: {
544: #if defined(PETSC_HAVE_AMS)
545: SNES v = (SNES) obj;
546: int ierr;
547: #endif
551: #if defined(PETSC_HAVE_AMS)
552: /* if it is already published then return */
553: if (v->amem >=0) return(0);
555: PetscObjectPublishBaseBegin(obj);
556: AMS_Memory_add_field((AMS_Memory)v->amem,"Iteration",&v->iter,1,AMS_INT,AMS_READ,
557: AMS_COMMON,AMS_REDUCT_UNDEF);
558: AMS_Memory_add_field((AMS_Memory)v->amem,"Residual",&v->norm,1,AMS_DOUBLE,AMS_READ,
559: AMS_COMMON,AMS_REDUCT_UNDEF);
560: PetscObjectPublishBaseEnd(obj);
561: #endif
562: return(0);
563: }
565: /* -----------------------------------------------------------*/
568: /*@C
569: SNESCreate - Creates a nonlinear solver context.
571: Collective on MPI_Comm
573: Input Parameters:
574: + comm - MPI communicator
576: Output Parameter:
577: . outsnes - the new SNES context
579: Options Database Keys:
580: + -snes_mf - Activates default matrix-free Jacobian-vector products,
581: and no preconditioning matrix
582: . -snes_mf_operator - Activates default matrix-free Jacobian-vector
583: products, and a user-provided preconditioning matrix
584: as set by SNESSetJacobian()
585: - -snes_fd - Uses (slow!) finite differences to compute Jacobian
587: Level: beginner
589: .keywords: SNES, nonlinear, create, context
591: .seealso: SNESSolve(), SNESDestroy(), SNES
592: @*/
593: int SNESCreate(MPI_Comm comm,SNES *outsnes)
594: {
595: int ierr;
596: SNES snes;
597: SNES_KSP_EW_ConvCtx *kctx;
601: *outsnes = PETSC_NULL;
602: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
603: SNESInitializePackage(PETSC_NULL);
604: #endif
606: PetscHeaderCreate(snes,_p_SNES,int,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);
607: PetscLogObjectCreate(snes);
608: snes->bops->publish = SNESPublish_Petsc;
609: snes->max_its = 50;
610: snes->max_funcs = 10000;
611: snes->norm = 0.0;
612: snes->rtol = 1.e-8;
613: snes->ttol = 0.0;
614: snes->atol = 1.e-50;
615: snes->xtol = 1.e-8;
616: snes->deltatol = 1.e-12;
617: snes->nfuncs = 0;
618: snes->numFailures = 0;
619: snes->maxFailures = 1;
620: snes->linear_its = 0;
621: snes->numbermonitors = 0;
622: snes->data = 0;
623: snes->view = 0;
624: snes->setupcalled = 0;
625: snes->ksp_ewconv = PETSC_FALSE;
626: snes->vwork = 0;
627: snes->nwork = 0;
628: snes->conv_hist_len = 0;
629: snes->conv_hist_max = 0;
630: snes->conv_hist = PETSC_NULL;
631: snes->conv_hist_its = PETSC_NULL;
632: snes->conv_hist_reset = PETSC_TRUE;
633: snes->reason = SNES_CONVERGED_ITERATING;
635: /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
636: PetscNew(SNES_KSP_EW_ConvCtx,&kctx);
637: PetscLogObjectMemory(snes,sizeof(SNES_KSP_EW_ConvCtx));
638: snes->kspconvctx = (void*)kctx;
639: kctx->version = 2;
640: kctx->rtol_0 = .3; /* Eisenstat and Walker suggest rtol_0=.5, but
641: this was too large for some test cases */
642: kctx->rtol_last = 0;
643: kctx->rtol_max = .9;
644: kctx->gamma = 1.0;
645: kctx->alpha2 = .5*(1.0 + sqrt(5.0));
646: kctx->alpha = kctx->alpha2;
647: kctx->threshold = .1;
648: kctx->lresid_last = 0;
649: kctx->norm_last = 0;
651: KSPCreate(comm,&snes->ksp);
652: PetscLogObjectParent(snes,snes->ksp)
654: *outsnes = snes;
655: PetscPublishAll(snes);
656: return(0);
657: }
659: /* --------------------------------------------------------------- */
662: /*@C
663: SNESSetFunction - Sets the function evaluation routine and function
664: vector for use by the SNES routines in solving systems of nonlinear
665: equations.
667: Collective on SNES
669: Input Parameters:
670: + snes - the SNES context
671: . func - function evaluation routine
672: . r - vector to store function value
673: - ctx - [optional] user-defined context for private data for the
674: function evaluation routine (may be PETSC_NULL)
676: Calling sequence of func:
677: $ func (SNES snes,Vec x,Vec f,void *ctx);
679: . f - function vector
680: - ctx - optional user-defined function context
682: Notes:
683: The Newton-like methods typically solve linear systems of the form
684: $ f'(x) x = -f(x),
685: where f'(x) denotes the Jacobian matrix and f(x) is the function.
687: Level: beginner
689: .keywords: SNES, nonlinear, set, function
691: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
692: @*/
693: int SNESSetFunction(SNES snes,Vec r,int (*func)(SNES,Vec,Vec,void*),void *ctx)
694: {
700: snes->computefunction = func;
701: snes->vec_func = snes->vec_func_always = r;
702: snes->funP = ctx;
703: return(0);
704: }
708: /*@
709: SNESComputeFunction - Calls the function that has been set with
710: SNESSetFunction().
712: Collective on SNES
714: Input Parameters:
715: + snes - the SNES context
716: - x - input vector
718: Output Parameter:
719: . y - function vector, as set by SNESSetFunction()
721: Notes:
722: SNESComputeFunction() is typically used within nonlinear solvers
723: implementations, so most users would not generally call this routine
724: themselves.
726: Level: developer
728: .keywords: SNES, nonlinear, compute, function
730: .seealso: SNESSetFunction(), SNESGetFunction()
731: @*/
732: int SNESComputeFunction(SNES snes,Vec x,Vec y)
733: {
734: int ierr;
743: PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0);
744: PetscStackPush("SNES user function");
745: (*snes->computefunction)(snes,x,y,snes->funP);
746: PetscStackPop;
747: snes->nfuncs++;
748: PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0);
749: return(0);
750: }
754: /*@
755: SNESComputeJacobian - Computes the Jacobian matrix that has been
756: set with SNESSetJacobian().
758: Collective on SNES and Mat
760: Input Parameters:
761: + snes - the SNES context
762: - x - input vector
764: Output Parameters:
765: + A - Jacobian matrix
766: . B - optional preconditioning matrix
767: - flag - flag indicating matrix structure
769: Notes:
770: Most users should not need to explicitly call this routine, as it
771: is used internally within the nonlinear solvers.
773: See KSPSetOperators() for important information about setting the
774: flag parameter.
776: Level: developer
778: .keywords: SNES, compute, Jacobian, matrix
780: .seealso: SNESSetJacobian(), KSPSetOperators()
781: @*/
782: int SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
783: {
784: int ierr;
791: if (!snes->computejacobian) return(0);
792: PetscLogEventBegin(SNES_JacobianEval,snes,X,*A,*B);
793: *flg = DIFFERENT_NONZERO_PATTERN;
794: PetscStackPush("SNES user Jacobian function");
795: (*snes->computejacobian)(snes,X,A,B,flg,snes->jacP);
796: PetscStackPop;
797: PetscLogEventEnd(SNES_JacobianEval,snes,X,*A,*B);
798: /* make sure user returned a correct Jacobian and preconditioner */
801: return(0);
802: }
806: /*@C
807: SNESSetJacobian - Sets the function to compute Jacobian as well as the
808: location to store the matrix.
810: Collective on SNES and Mat
812: Input Parameters:
813: + snes - the SNES context
814: . A - Jacobian matrix
815: . B - preconditioner matrix (usually same as the Jacobian)
816: . func - Jacobian evaluation routine
817: - ctx - [optional] user-defined context for private data for the
818: Jacobian evaluation routine (may be PETSC_NULL)
820: Calling sequence of func:
821: $ func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);
823: + x - input vector
824: . A - Jacobian matrix
825: . B - preconditioner matrix, usually the same as A
826: . flag - flag indicating information about the preconditioner matrix
827: structure (same as flag in KSPSetOperators())
828: - ctx - [optional] user-defined Jacobian context
830: Notes:
831: See KSPSetOperators() for important information about setting the flag
832: output parameter in the routine func(). Be sure to read this information!
834: The routine func() takes Mat * as the matrix arguments rather than Mat.
835: This allows the Jacobian evaluation routine to replace A and/or B with a
836: completely new new matrix structure (not just different matrix elements)
837: when appropriate, for instance, if the nonzero structure is changing
838: throughout the global iterations.
840: Level: beginner
842: .keywords: SNES, nonlinear, set, Jacobian, matrix
844: .seealso: KSPSetOperators(), SNESSetFunction()
845: @*/
846: int SNESSetJacobian(SNES snes,Mat A,Mat B,int (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
847: {
856: if (func) snes->computejacobian = func;
857: if (ctx) snes->jacP = ctx;
858: if (A) {
859: if (snes->jacobian) {MatDestroy(snes->jacobian);}
860: snes->jacobian = A;
861: PetscObjectReference((PetscObject)A);
862: }
863: if (B) {
864: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
865: snes->jacobian_pre = B;
866: PetscObjectReference((PetscObject)B);
867: }
868: return(0);
869: }
873: /*@C
874: SNESGetJacobian - Returns the Jacobian matrix and optionally the user
875: provided context for evaluating the Jacobian.
877: Not Collective, but Mat object will be parallel if SNES object is
879: Input Parameter:
880: . snes - the nonlinear solver context
882: Output Parameters:
883: + A - location to stash Jacobian matrix (or PETSC_NULL)
884: . B - location to stash preconditioner matrix (or PETSC_NULL)
885: . ctx - location to stash Jacobian ctx (or PETSC_NULL)
886: - func - location to put Jacobian function (or PETSC_NULL)
888: Level: advanced
890: .seealso: SNESSetJacobian(), SNESComputeJacobian()
891: @*/
892: int SNESGetJacobian(SNES snes,Mat *A,Mat *B,void **ctx,int (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*))
893: {
896: if (A) *A = snes->jacobian;
897: if (B) *B = snes->jacobian_pre;
898: if (ctx) *ctx = snes->jacP;
899: if (func) *func = snes->computejacobian;
900: return(0);
901: }
903: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
904: extern int SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);
908: /*@
909: SNESSetUp - Sets up the internal data structures for the later use
910: of a nonlinear solver.
912: Collective on SNES
914: Input Parameters:
915: + snes - the SNES context
916: - x - the solution vector
918: Notes:
919: For basic use of the SNES solvers the user need not explicitly call
920: SNESSetUp(), since these actions will automatically occur during
921: the call to SNESSolve(). However, if one wishes to control this
922: phase separately, SNESSetUp() should be called after SNESCreate()
923: and optional routines of the form SNESSetXXX(), but before SNESSolve().
925: Level: advanced
927: .keywords: SNES, nonlinear, setup
929: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
930: @*/
931: int SNESSetUp(SNES snes,Vec x)
932: {
933: int ierr;
934: PetscTruth flg, iseqtr;
940: snes->vec_sol = snes->vec_sol_always = x;
942: PetscOptionsHasName(snes->prefix,"-snes_mf_operator",&flg);
943: /*
944: This version replaces the user provided Jacobian matrix with a
945: matrix-free version but still employs the user-provided preconditioner matrix
946: */
947: if (flg) {
948: Mat J;
949: MatCreateSNESMF(snes,snes->vec_sol,&J);
950: MatSNESMFSetFromOptions(J);
951: PetscLogInfo(snes,"SNESSetUp: Setting default matrix-free operator routines\n");
952: SNESSetJacobian(snes,J,0,0,0);
953: MatDestroy(J);
954: }
956: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
957: PetscOptionsHasName(snes->prefix,"-snes_mf_operator2",&flg);
958: if (flg) {
959: Mat J;
960: SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
961: SNESSetJacobian(snes,J,0,0,0);
962: MatDestroy(J);
963: }
964: #endif
966: PetscOptionsHasName(snes->prefix,"-snes_mf",&flg);
967: /*
968: This version replaces both the user-provided Jacobian and the user-
969: provided preconditioner matrix with the default matrix free version.
970: */
971: if (flg) {
972: Mat J;
973: KSP ksp;
974: PC pc;
976: MatCreateSNESMF(snes,snes->vec_sol,&J);
977: MatSNESMFSetFromOptions(J);
978: PetscLogInfo(snes,"SNESSetUp: Setting default matrix-free operator and preconditioner routines\n");
979: SNESSetJacobian(snes,J,J,MatSNESMFComputeJacobian,snes->funP);
980: MatDestroy(J);
982: /* force no preconditioner */
983: SNESGetKSP(snes,&ksp);
984: KSPGetPC(ksp,&pc);
985: PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
986: if (!flg) {
987: PCSetType(pc,PCNONE);
988: }
989: }
991: if (!snes->vec_func) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
992: if (!snes->computefunction) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
993: if (!snes->jacobian) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
994: if (snes->vec_func == snes->vec_sol) {
995: SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
996: }
998: /* Set the KSP stopping criterion to use the Eisenstat-Walker method */
999: PetscTypeCompare((PetscObject)snes,SNESTR,&iseqtr);
1000: if (snes->ksp_ewconv && !iseqtr) {
1001: KSP ksp;
1002: SNESGetKSP(snes,&ksp);
1003: KSPSetConvergenceTest(ksp,SNES_KSP_EW_Converged_Private,snes);
1004: }
1006: if (snes->setup) {(*snes->setup)(snes);}
1007: snes->setupcalled = 1;
1008: return(0);
1009: }
1013: /*@C
1014: SNESDestroy - Destroys the nonlinear solver context that was created
1015: with SNESCreate().
1017: Collective on SNES
1019: Input Parameter:
1020: . snes - the SNES context
1022: Level: beginner
1024: .keywords: SNES, nonlinear, destroy
1026: .seealso: SNESCreate(), SNESSolve()
1027: @*/
1028: int SNESDestroy(SNES snes)
1029: {
1030: int i,ierr;
1034: if (--snes->refct > 0) return(0);
1036: /* if memory was published with AMS then destroy it */
1037: PetscObjectDepublish(snes);
1039: if (snes->destroy) {(*(snes)->destroy)(snes);}
1040: if (snes->kspconvctx) {PetscFree(snes->kspconvctx);}
1041: if (snes->jacobian) {MatDestroy(snes->jacobian);}
1042: if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1043: KSPDestroy(snes->ksp);
1044: if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1045: for (i=0; i<snes->numbermonitors; i++) {
1046: if (snes->monitordestroy[i]) {
1047: (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1048: }
1049: }
1050: PetscLogObjectDestroy((PetscObject)snes);
1051: PetscHeaderDestroy((PetscObject)snes);
1052: return(0);
1053: }
1055: /* ----------- Routines to set solver parameters ---------- */
1059: /*@
1060: SNESSetTolerances - Sets various parameters used in convergence tests.
1062: Collective on SNES
1064: Input Parameters:
1065: + snes - the SNES context
1066: . atol - absolute convergence tolerance
1067: . rtol - relative convergence tolerance
1068: . stol - convergence tolerance in terms of the norm
1069: of the change in the solution between steps
1070: . maxit - maximum number of iterations
1071: - maxf - maximum number of function evaluations
1073: Options Database Keys:
1074: + -snes_atol <atol> - Sets atol
1075: . -snes_rtol <rtol> - Sets rtol
1076: . -snes_stol <stol> - Sets stol
1077: . -snes_max_it <maxit> - Sets maxit
1078: - -snes_max_funcs <maxf> - Sets maxf
1080: Notes:
1081: The default maximum number of iterations is 50.
1082: The default maximum number of function evaluations is 1000.
1084: Level: intermediate
1086: .keywords: SNES, nonlinear, set, convergence, tolerances
1088: .seealso: SNESSetTrustRegionTolerance(), SNESSetMinimizationFunctionTolerance()
1089: @*/
1090: int SNESSetTolerances(SNES snes,PetscReal atol,PetscReal rtol,PetscReal stol,int maxit,int maxf)
1091: {
1094: if (atol != PETSC_DEFAULT) snes->atol = atol;
1095: if (rtol != PETSC_DEFAULT) snes->rtol = rtol;
1096: if (stol != PETSC_DEFAULT) snes->xtol = stol;
1097: if (maxit != PETSC_DEFAULT) snes->max_its = maxit;
1098: if (maxf != PETSC_DEFAULT) snes->max_funcs = maxf;
1099: return(0);
1100: }
1104: /*@
1105: SNESGetTolerances - Gets various parameters used in convergence tests.
1107: Not Collective
1109: Input Parameters:
1110: + snes - the SNES context
1111: . atol - absolute convergence tolerance
1112: . rtol - relative convergence tolerance
1113: . stol - convergence tolerance in terms of the norm
1114: of the change in the solution between steps
1115: . maxit - maximum number of iterations
1116: - maxf - maximum number of function evaluations
1118: Notes:
1119: The user can specify PETSC_NULL for any parameter that is not needed.
1121: Level: intermediate
1123: .keywords: SNES, nonlinear, get, convergence, tolerances
1125: .seealso: SNESSetTolerances()
1126: @*/
1127: int SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,int *maxit,int *maxf)
1128: {
1131: if (atol) *atol = snes->atol;
1132: if (rtol) *rtol = snes->rtol;
1133: if (stol) *stol = snes->xtol;
1134: if (maxit) *maxit = snes->max_its;
1135: if (maxf) *maxf = snes->max_funcs;
1136: return(0);
1137: }
1141: /*@
1142: SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.
1144: Collective on SNES
1146: Input Parameters:
1147: + snes - the SNES context
1148: - tol - tolerance
1149:
1150: Options Database Key:
1151: . -snes_trtol <tol> - Sets tol
1153: Level: intermediate
1155: .keywords: SNES, nonlinear, set, trust region, tolerance
1157: .seealso: SNESSetTolerances(), SNESSetMinimizationFunctionTolerance()
1158: @*/
1159: int SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1160: {
1163: snes->deltatol = tol;
1164: return(0);
1165: }
1167: /*
1168: Duplicate the lg monitors for SNES from KSP; for some reason with
1169: dynamic libraries things don't work under Sun4 if we just use
1170: macros instead of functions
1171: */
1174: int SNESLGMonitor(SNES snes,int it,PetscReal norm,void *ctx)
1175: {
1180: KSPLGMonitor((KSP)snes,it,norm,ctx);
1181: return(0);
1182: }
1186: int SNESLGMonitorCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1187: {
1191: KSPLGMonitorCreate(host,label,x,y,m,n,draw);
1192: return(0);
1193: }
1197: int SNESLGMonitorDestroy(PetscDrawLG draw)
1198: {
1202: KSPLGMonitorDestroy(draw);
1203: return(0);
1204: }
1206: /* ------------ Routines to set performance monitoring options ----------- */
1210: /*@C
1211: SNESSetMonitor - Sets an ADDITIONAL function that is to be used at every
1212: iteration of the nonlinear solver to display the iteration's
1213: progress.
1215: Collective on SNES
1217: Input Parameters:
1218: + snes - the SNES context
1219: . func - monitoring routine
1220: . mctx - [optional] user-defined context for private data for the
1221: monitor routine (use PETSC_NULL if no context is desitre)
1222: - monitordestroy - [optional] routine that frees monitor context
1223: (may be PETSC_NULL)
1225: Calling sequence of func:
1226: $ int func(SNES snes,int its, PetscReal norm,void *mctx)
1228: + snes - the SNES context
1229: . its - iteration number
1230: . norm - 2-norm function value (may be estimated)
1231: - mctx - [optional] monitoring context
1233: Options Database Keys:
1234: + -snes_monitor - sets SNESDefaultMonitor()
1235: . -snes_xmonitor - sets line graph monitor,
1236: uses SNESLGMonitorCreate()
1237: _ -snes_cancelmonitors - cancels all monitors that have
1238: been hardwired into a code by
1239: calls to SNESSetMonitor(), but
1240: does not cancel those set via
1241: the options database.
1243: Notes:
1244: Several different monitoring routines may be set by calling
1245: SNESSetMonitor() multiple times; all will be called in the
1246: order in which they were set.
1248: Level: intermediate
1250: .keywords: SNES, nonlinear, set, monitor
1252: .seealso: SNESDefaultMonitor(), SNESClearMonitor()
1253: @*/
1254: int SNESSetMonitor(SNES snes,int (*func)(SNES,int,PetscReal,void*),void *mctx,int (*monitordestroy)(void *))
1255: {
1258: if (snes->numbermonitors >= MAXSNESMONITORS) {
1259: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1260: }
1262: snes->monitor[snes->numbermonitors] = func;
1263: snes->monitordestroy[snes->numbermonitors] = monitordestroy;
1264: snes->monitorcontext[snes->numbermonitors++] = (void*)mctx;
1265: return(0);
1266: }
1270: /*@C
1271: SNESClearMonitor - Clears all the monitor functions for a SNES object.
1273: Collective on SNES
1275: Input Parameters:
1276: . snes - the SNES context
1278: Options Database Key:
1279: . -snes_cancelmonitors - cancels all monitors that have been hardwired
1280: into a code by calls to SNESSetMonitor(), but does not cancel those
1281: set via the options database
1283: Notes:
1284: There is no way to clear one specific monitor from a SNES object.
1286: Level: intermediate
1288: .keywords: SNES, nonlinear, set, monitor
1290: .seealso: SNESDefaultMonitor(), SNESSetMonitor()
1291: @*/
1292: int SNESClearMonitor(SNES snes)
1293: {
1296: snes->numbermonitors = 0;
1297: return(0);
1298: }
1302: /*@C
1303: SNESSetConvergenceTest - Sets the function that is to be used
1304: to test for convergence of the nonlinear iterative solution.
1306: Collective on SNES
1308: Input Parameters:
1309: + snes - the SNES context
1310: . func - routine to test for convergence
1311: - cctx - [optional] context for private data for the convergence routine
1312: (may be PETSC_NULL)
1314: Calling sequence of func:
1315: $ int func (SNES snes,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)
1317: + snes - the SNES context
1318: . cctx - [optional] convergence context
1319: . reason - reason for convergence/divergence
1320: . xnorm - 2-norm of current iterate
1321: . gnorm - 2-norm of current step
1322: - f - 2-norm of function
1324: Level: advanced
1326: .keywords: SNES, nonlinear, set, convergence, test
1328: .seealso: SNESConverged_LS(), SNESConverged_TR()
1329: @*/
1330: int SNESSetConvergenceTest(SNES snes,int (*func)(SNES,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1331: {
1334: (snes)->converged = func;
1335: (snes)->cnvP = cctx;
1336: return(0);
1337: }
1341: /*@C
1342: SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.
1344: Not Collective
1346: Input Parameter:
1347: . snes - the SNES context
1349: Output Parameter:
1350: . reason - negative value indicates diverged, positive value converged, see petscsnes.h or the
1351: manual pages for the individual convergence tests for complete lists
1353: Level: intermediate
1355: Notes: Can only be called after the call the SNESSolve() is complete.
1357: .keywords: SNES, nonlinear, set, convergence, test
1359: .seealso: SNESSetConvergenceTest(), SNESConverged_LS(), SNESConverged_TR(), SNESConvergedReason
1360: @*/
1361: int SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1362: {
1366: *reason = snes->reason;
1367: return(0);
1368: }
1372: /*@
1373: SNESSetConvergenceHistory - Sets the array used to hold the convergence history.
1375: Collective on SNES
1377: Input Parameters:
1378: + snes - iterative context obtained from SNESCreate()
1379: . a - array to hold history
1380: . its - integer array holds the number of linear iterations for each solve.
1381: . na - size of a and its
1382: - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1383: else it continues storing new values for new nonlinear solves after the old ones
1385: Notes:
1386: If set, this array will contain the function norms computed
1387: at each step.
1389: This routine is useful, e.g., when running a code for purposes
1390: of accurate performance monitoring, when no I/O should be done
1391: during the section of code that is being timed.
1393: Level: intermediate
1395: .keywords: SNES, set, convergence, history
1397: .seealso: SNESGetConvergenceHistory()
1399: @*/
1400: int SNESSetConvergenceHistory(SNES snes,PetscReal a[],int *its,int na,PetscTruth reset)
1401: {
1405: snes->conv_hist = a;
1406: snes->conv_hist_its = its;
1407: snes->conv_hist_max = na;
1408: snes->conv_hist_reset = reset;
1409: return(0);
1410: }
1414: /*@C
1415: SNESGetConvergenceHistory - Gets the array used to hold the convergence history.
1417: Collective on SNES
1419: Input Parameter:
1420: . snes - iterative context obtained from SNESCreate()
1422: Output Parameters:
1423: . a - array to hold history
1424: . its - integer array holds the number of linear iterations (or
1425: negative if not converged) for each solve.
1426: - na - size of a and its
1428: Notes:
1429: The calling sequence for this routine in Fortran is
1430: $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)
1432: This routine is useful, e.g., when running a code for purposes
1433: of accurate performance monitoring, when no I/O should be done
1434: during the section of code that is being timed.
1436: Level: intermediate
1438: .keywords: SNES, get, convergence, history
1440: .seealso: SNESSetConvergencHistory()
1442: @*/
1443: int SNESGetConvergenceHistory(SNES snes,PetscReal *a[],int *its[],int *na)
1444: {
1447: if (a) *a = snes->conv_hist;
1448: if (its) *its = snes->conv_hist_its;
1449: if (na) *na = snes->conv_hist_len;
1450: return(0);
1451: }
1455: /*@C
1456: SNESSetRhsBC - Sets the function which applies boundary conditions
1457: to the Rhs of each system.
1459: Collective on SNES
1461: Input Parameters:
1462: . snes - The nonlinear solver context
1463: . func - The function
1465: Calling sequence of func:
1466: . func (SNES snes, Vec rhs, void *ctx);
1468: . rhs - The current rhs vector
1469: . ctx - The user-context
1471: Level: intermediate
1473: .keywords: SNES, Rhs, boundary conditions
1474: .seealso SNESDefaultRhsBC(), SNESSetSolutionBC(), SNESSetUpdate()
1475: @*/
1476: int SNESSetRhsBC(SNES snes, int (*func)(SNES, Vec, void *))
1477: {
1480: snes->applyrhsbc = func;
1481: return(0);
1482: }
1486: /*@
1487: SNESDefaultRhsBC - The default boundary condition function which does nothing.
1489: Not collective
1491: Input Parameters:
1492: . snes - The nonlinear solver context
1493: . rhs - The Rhs
1494: . ctx - The user-context
1496: Level: beginner
1498: .keywords: SNES, Rhs, boundary conditions
1499: .seealso SNESSetRhsBC(), SNESDefaultSolutionBC(), SNESDefaultUpdate()
1500: @*/
1501: int SNESDefaultRhsBC(SNES snes, Vec rhs, void *ctx)
1502: {
1504: return(0);
1505: }
1509: /*@C
1510: SNESSetSolutionBC - Sets the function which applies boundary conditions
1511: to the solution of each system.
1513: Collective on SNES
1515: Input Parameters:
1516: . snes - The nonlinear solver context
1517: . func - The function
1519: Calling sequence of func:
1520: . func (SNES snes, Vec rsol, void *ctx);
1522: . sol - The current solution vector
1523: . ctx - The user-context
1525: Level: intermediate
1527: .keywords: SNES, solution, boundary conditions
1528: .seealso SNESDefaultSolutionBC(), SNESSetRhsBC(), SNESSetUpdate()
1529: @*/
1530: int SNESSetSolutionBC(SNES snes, int (*func)(SNES, Vec, void *))
1531: {
1534: snes->applysolbc = func;
1535: return(0);
1536: }
1540: /*@
1541: SNESDefaultSolutionBC - The default boundary condition function which does nothing.
1543: Not collective
1545: Input Parameters:
1546: . snes - The nonlinear solver context
1547: . sol - The solution
1548: . ctx - The user-context
1550: Level: beginner
1552: .keywords: SNES, solution, boundary conditions
1553: .seealso SNESSetSolutionBC(), SNESDefaultRhsBC(), SNESDefaultUpdate()
1554: @*/
1555: int SNESDefaultSolutionBC(SNES snes, Vec sol, void *ctx)
1556: {
1558: return(0);
1559: }
1563: /*@C
1564: SNESSetUpdate - Sets the general-purpose update function called
1565: at the beginning of every step of the iteration.
1567: Collective on SNES
1569: Input Parameters:
1570: . snes - The nonlinear solver context
1571: . func - The function
1573: Calling sequence of func:
1574: . func (TS ts, int step);
1576: . step - The current step of the iteration
1578: Level: intermediate
1580: .keywords: SNES, update
1581: .seealso SNESDefaultUpdate(), SNESSetRhsBC(), SNESSetSolutionBC()
1582: @*/
1583: int SNESSetUpdate(SNES snes, int (*func)(SNES, int))
1584: {
1587: snes->update = func;
1588: return(0);
1589: }
1593: /*@
1594: SNESDefaultUpdate - The default update function which does nothing.
1596: Not collective
1598: Input Parameters:
1599: . snes - The nonlinear solver context
1600: . step - The current step of the iteration
1602: Level: intermediate
1604: .keywords: SNES, update
1605: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultSolutionBC()
1606: @*/
1607: int SNESDefaultUpdate(SNES snes, int step)
1608: {
1610: return(0);
1611: }
1615: /*
1616: SNESScaleStep_Private - Scales a step so that its length is less than the
1617: positive parameter delta.
1619: Input Parameters:
1620: + snes - the SNES context
1621: . y - approximate solution of linear system
1622: . fnorm - 2-norm of current function
1623: - delta - trust region size
1625: Output Parameters:
1626: + gpnorm - predicted function norm at the new point, assuming local
1627: linearization. The value is zero if the step lies within the trust
1628: region, and exceeds zero otherwise.
1629: - ynorm - 2-norm of the step
1631: Note:
1632: For non-trust region methods such as SNESLS, the parameter delta
1633: is set to be the maximum allowable step size.
1635: .keywords: SNES, nonlinear, scale, step
1636: */
1637: int SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1638: {
1639: PetscReal nrm;
1640: PetscScalar cnorm;
1641: int ierr;
1648: VecNorm(y,NORM_2,&nrm);
1649: if (nrm > *delta) {
1650: nrm = *delta/nrm;
1651: *gpnorm = (1.0 - nrm)*(*fnorm);
1652: cnorm = nrm;
1653: VecScale(&cnorm,y);
1654: *ynorm = *delta;
1655: } else {
1656: *gpnorm = 0.0;
1657: *ynorm = nrm;
1658: }
1659: return(0);
1660: }
1664: /*@
1665: SNESSolve - Solves a nonlinear system. Call SNESSolve after calling
1666: SNESCreate() and optional routines of the form SNESSetXXX().
1668: Collective on SNES
1670: Input Parameters:
1671: + snes - the SNES context
1672: - x - the solution vector
1674: Notes:
1675: The user should initialize the vector,x, with the initial guess
1676: for the nonlinear solve prior to calling SNESSolve. In particular,
1677: to employ an initial guess of zero, the user should explicitly set
1678: this vector to zero by calling VecSet().
1680: Level: beginner
1682: .keywords: SNES, nonlinear, solve
1684: .seealso: SNESCreate(), SNESDestroy()
1685: @*/
1686: int SNESSolve(SNES snes,Vec x)
1687: {
1688: int ierr;
1689: PetscTruth flg;
1695: if (!snes->solve) SETERRQ(1,"SNESSetType() or SNESSetFromOptions() must be called before SNESSolve()");
1697: if (!snes->setupcalled) {SNESSetUp(snes,x);}
1698: else {snes->vec_sol = snes->vec_sol_always = x;}
1699: if (snes->conv_hist_reset == PETSC_TRUE) snes->conv_hist_len = 0;
1700: PetscLogEventBegin(SNES_Solve,snes,0,0,0);
1701: snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;
1702: (*(snes)->solve)(snes);
1703: PetscLogEventEnd(SNES_Solve,snes,0,0,0);
1704: PetscOptionsHasName(snes->prefix,"-snes_view",&flg);
1705: if (flg && !PetscPreLoadingOn) { SNESView(snes,PETSC_VIEWER_STDOUT_(snes->comm)); }
1706: PetscOptionsHasName(snes->prefix,"-snes_test_local_min",&flg);
1707: if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1708: return(0);
1709: }
1711: /* --------- Internal routines for SNES Package --------- */
1715: /*@C
1716: SNESSetType - Sets the method for the nonlinear solver.
1718: Collective on SNES
1720: Input Parameters:
1721: + snes - the SNES context
1722: - type - a known method
1724: Options Database Key:
1725: . -snes_type <type> - Sets the method; use -help for a list
1726: of available methods (for instance, ls or tr)
1728: Notes:
1729: See "petsc/include/petscsnes.h" for available methods (for instance)
1730: + SNESLS - Newton's method with line search
1731: (systems of nonlinear equations)
1732: . SNESTR - Newton's method with trust region
1733: (systems of nonlinear equations)
1735: Normally, it is best to use the SNESSetFromOptions() command and then
1736: set the SNES solver type from the options database rather than by using
1737: this routine. Using the options database provides the user with
1738: maximum flexibility in evaluating the many nonlinear solvers.
1739: The SNESSetType() routine is provided for those situations where it
1740: is necessary to set the nonlinear solver independently of the command
1741: line or options database. This might be the case, for example, when
1742: the choice of solver changes during the execution of the program,
1743: and the user's application is taking responsibility for choosing the
1744: appropriate method.
1746: Level: intermediate
1748: .keywords: SNES, set, type
1750: .seealso: SNESType, SNESCreate()
1752: @*/
1753: int SNESSetType(SNES snes,const SNESType type)
1754: {
1755: int ierr,(*r)(SNES);
1756: PetscTruth match;
1762: PetscTypeCompare((PetscObject)snes,type,&match);
1763: if (match) return(0);
1765: if (snes->setupcalled) {
1766: (*(snes)->destroy)(snes);
1767: snes->data = 0;
1768: }
1770: /* Get the function pointers for the iterative method requested */
1771: if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
1773: PetscFListFind(snes->comm,SNESList,type,(void (**)(void)) &r);
1775: if (!r) SETERRQ1(1,"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);
1782: return(0);
1783: }
1786: /* --------------------------------------------------------------------- */
1789: /*@C
1790: SNESRegisterDestroy - Frees the list of nonlinear solvers that were
1791: registered by SNESRegisterDynamic().
1793: Not Collective
1795: Level: advanced
1797: .keywords: SNES, nonlinear, register, destroy
1799: .seealso: SNESRegisterAll(), SNESRegisterAll()
1800: @*/
1801: int SNESRegisterDestroy(void)
1802: {
1806: if (SNESList) {
1807: PetscFListDestroy(&SNESList);
1808: SNESList = 0;
1809: }
1810: SNESRegisterAllCalled = PETSC_FALSE;
1811: return(0);
1812: }
1816: /*@C
1817: SNESGetType - Gets the SNES method type and name (as a string).
1819: Not Collective
1821: Input Parameter:
1822: . snes - nonlinear solver context
1824: Output Parameter:
1825: . type - SNES method (a character string)
1827: Level: intermediate
1829: .keywords: SNES, nonlinear, get, type, name
1830: @*/
1831: int SNESGetType(SNES snes,SNESType *type)
1832: {
1836: *type = snes->type_name;
1837: return(0);
1838: }
1842: /*@C
1843: SNESGetSolution - Returns the vector where the approximate solution is
1844: stored.
1846: Not Collective, but Vec is parallel if SNES is parallel
1848: Input Parameter:
1849: . snes - the SNES context
1851: Output Parameter:
1852: . x - the solution
1854: Level: advanced
1856: .keywords: SNES, nonlinear, get, solution
1858: .seealso: SNESGetFunction(), SNESGetSolutionUpdate()
1859: @*/
1860: int SNESGetSolution(SNES snes,Vec *x)
1861: {
1865: *x = snes->vec_sol_always;
1866: return(0);
1867: }
1871: /*@C
1872: SNESGetSolutionUpdate - Returns the vector where the solution update is
1873: stored.
1875: Not Collective, but Vec is parallel if SNES is parallel
1877: Input Parameter:
1878: . snes - the SNES context
1880: Output Parameter:
1881: . x - the solution update
1883: Level: advanced
1885: .keywords: SNES, nonlinear, get, solution, update
1887: .seealso: SNESGetSolution(), SNESGetFunction
1888: @*/
1889: int SNESGetSolutionUpdate(SNES snes,Vec *x)
1890: {
1894: *x = snes->vec_sol_update_always;
1895: return(0);
1896: }
1900: /*@C
1901: SNESGetFunction - Returns the vector where the function is stored.
1903: Not Collective, but Vec is parallel if SNES is parallel
1905: Input Parameter:
1906: . snes - the SNES context
1908: Output Parameter:
1909: + r - the function (or PETSC_NULL)
1910: . ctx - the function context (or PETSC_NULL)
1911: - func - the function (or PETSC_NULL)
1913: Level: advanced
1915: .keywords: SNES, nonlinear, get, function
1917: .seealso: SNESSetFunction(), SNESGetSolution()
1918: @*/
1919: int SNESGetFunction(SNES snes,Vec *r,void **ctx,int (**func)(SNES,Vec,Vec,void*))
1920: {
1923: if (r) *r = snes->vec_func_always;
1924: if (ctx) *ctx = snes->funP;
1925: if (func) *func = snes->computefunction;
1926: return(0);
1927: }
1931: /*@C
1932: SNESSetOptionsPrefix - Sets the prefix used for searching for all
1933: SNES options in the database.
1935: Collective on SNES
1937: Input Parameter:
1938: + snes - the SNES context
1939: - prefix - the prefix to prepend to all option names
1941: Notes:
1942: A hyphen (-) must NOT be given at the beginning of the prefix name.
1943: The first character of all runtime options is AUTOMATICALLY the hyphen.
1945: Level: advanced
1947: .keywords: SNES, set, options, prefix, database
1949: .seealso: SNESSetFromOptions()
1950: @*/
1951: int SNESSetOptionsPrefix(SNES snes,const char prefix[])
1952: {
1957: PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
1958: KSPSetOptionsPrefix(snes->ksp,prefix);
1959: return(0);
1960: }
1964: /*@C
1965: SNESAppendOptionsPrefix - Appends to the prefix used for searching for all
1966: SNES options in the database.
1968: Collective on SNES
1970: Input Parameters:
1971: + snes - the SNES context
1972: - prefix - the prefix to prepend to all option names
1974: Notes:
1975: A hyphen (-) must NOT be given at the beginning of the prefix name.
1976: The first character of all runtime options is AUTOMATICALLY the hyphen.
1978: Level: advanced
1980: .keywords: SNES, append, options, prefix, database
1982: .seealso: SNESGetOptionsPrefix()
1983: @*/
1984: int SNESAppendOptionsPrefix(SNES snes,const char prefix[])
1985: {
1987:
1990: PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
1991: KSPAppendOptionsPrefix(snes->ksp,prefix);
1992: return(0);
1993: }
1997: /*@C
1998: SNESGetOptionsPrefix - Sets the prefix used for searching for all
1999: SNES options in the database.
2001: Not Collective
2003: Input Parameter:
2004: . snes - the SNES context
2006: Output Parameter:
2007: . prefix - pointer to the prefix string used
2009: Notes: On the fortran side, the user should pass in a string 'prifix' of
2010: sufficient length to hold the prefix.
2012: Level: advanced
2014: .keywords: SNES, get, options, prefix, database
2016: .seealso: SNESAppendOptionsPrefix()
2017: @*/
2018: int SNESGetOptionsPrefix(SNES snes,char *prefix[])
2019: {
2024: PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2025: return(0);
2026: }
2031: /*@C
2032: SNESRegister - See SNESRegisterDynamic()
2034: Level: advanced
2035: @*/
2036: int SNESRegister(const char sname[],const char path[],const char name[],int (*function)(SNES))
2037: {
2038: char fullname[256];
2039: int ierr;
2042: PetscFListConcat(path,name,fullname);
2043: PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2044: return(0);
2045: }
2049: int SNESTestLocalMin(SNES snes)
2050: {
2051: int ierr,N,i,j;
2052: Vec u,uh,fh;
2053: PetscScalar value;
2054: PetscReal norm;
2057: SNESGetSolution(snes,&u);
2058: VecDuplicate(u,&uh);
2059: VecDuplicate(u,&fh);
2061: /* currently only works for sequential */
2062: PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2063: VecGetSize(u,&N);
2064: for (i=0; i<N; i++) {
2065: VecCopy(u,uh);
2066: PetscPrintf(PETSC_COMM_WORLD,"i = %d\n",i);
2067: for (j=-10; j<11; j++) {
2068: value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2069: VecSetValue(uh,i,value,ADD_VALUES);
2070: (*snes->computefunction)(snes,uh,fh,snes->funP);
2071: VecNorm(fh,NORM_2,&norm);
2072: PetscPrintf(PETSC_COMM_WORLD," j norm %d %18.16e\n",j,norm);
2073: value = -value;
2074: VecSetValue(uh,i,value,ADD_VALUES);
2075: }
2076: }
2077: VecDestroy(uh);
2078: VecDestroy(fh);
2079: return(0);
2080: }