Actual source code: snes.c

  1: #define PETSCSNES_DLL

 3:  #include include/private/snesimpl.h

  5: PetscTruth SNESRegisterAllCalled = PETSC_FALSE;
  6: PetscFList SNESList              = PETSC_NULL;

  8: /* Logging support */
  9: PetscCookie  SNES_COOKIE = 0;
 10: PetscEvent  SNES_Solve = 0, SNES_LineSearch = 0, SNES_FunctionEval = 0, SNES_JacobianEval = 0;

 14: /*@C
 15:    SNESSetFunctionDomainError - tells SNES that the input vector to your FormFunction is not
 16:      in the functions domain. For example, negative pressure.

 18:    Collective on SNES

 20:    Input Parameters:
 21: .  SNES - the SNES context

 23:    Level: advanced

 25: .keywords: SNES, view

 27: .seealso: SNESCreate(), SNESSetFunction()
 28: @*/
 29: PetscErrorCode  SNESSetFunctionDomainError(SNES snes)
 30: {
 33:   snes->domainerror = PETSC_TRUE;
 34:   return(0);
 35: }

 39: /*@C
 40:    SNESView - Prints the SNES data structure.

 42:    Collective on SNES

 44:    Input Parameters:
 45: +  SNES - the SNES context
 46: -  viewer - visualization context

 48:    Options Database Key:
 49: .  -snes_view - Calls SNESView() at end of SNESSolve()

 51:    Notes:
 52:    The available visualization contexts include
 53: +     PETSC_VIEWER_STDOUT_SELF - standard output (default)
 54: -     PETSC_VIEWER_STDOUT_WORLD - synchronized standard
 55:          output where only the first processor opens
 56:          the file.  All other processors send their 
 57:          data to the first processor to print. 

 59:    The user can open an alternative visualization context with
 60:    PetscViewerASCIIOpen() - output to a specified file.

 62:    Level: beginner

 64: .keywords: SNES, view

 66: .seealso: PetscViewerASCIIOpen()
 67: @*/
 68: PetscErrorCode  SNESView(SNES snes,PetscViewer viewer)
 69: {
 70:   SNESKSPEW           *kctx;
 71:   PetscErrorCode      ierr;
 72:   KSP                 ksp;
 73:   SNESType            type;
 74:   PetscTruth          iascii,isstring;

 78:   if (!viewer) {
 79:     PetscViewerASCIIGetStdout(((PetscObject)snes)->comm,&viewer);
 80:   }

 84:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
 85:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);
 86:   if (iascii) {
 87:     if (((PetscObject)snes)->prefix) {
 88:       PetscViewerASCIIPrintf(viewer,"SNES Object:(%s)\n",((PetscObject)snes)->prefix);
 89:     } else {
 90:       PetscViewerASCIIPrintf(viewer,"SNES Object:\n");
 91:     }
 92:     SNESGetType(snes,&type);
 93:     if (type) {
 94:       PetscViewerASCIIPrintf(viewer,"  type: %s\n",type);
 95:     } else {
 96:       PetscViewerASCIIPrintf(viewer,"  type: not set yet\n");
 97:     }
 98:     if (snes->ops->view) {
 99:       PetscViewerASCIIPushTab(viewer);
100:       (*snes->ops->view)(snes,viewer);
101:       PetscViewerASCIIPopTab(viewer);
102:     }
103:     PetscViewerASCIIPrintf(viewer,"  maximum iterations=%D, maximum function evaluations=%D\n",snes->max_its,snes->max_funcs);
104:     PetscViewerASCIIPrintf(viewer,"  tolerances: relative=%G, absolute=%G, solution=%G\n",
105:                  snes->rtol,snes->abstol,snes->xtol);
106:     PetscViewerASCIIPrintf(viewer,"  total number of linear solver iterations=%D\n",snes->linear_its);
107:     PetscViewerASCIIPrintf(viewer,"  total number of function evaluations=%D\n",snes->nfuncs);
108:     if (snes->ksp_ewconv) {
109:       kctx = (SNESKSPEW *)snes->kspconvctx;
110:       if (kctx) {
111:         PetscViewerASCIIPrintf(viewer,"  Eisenstat-Walker computation of KSP relative tolerance (version %D)\n",kctx->version);
112:         PetscViewerASCIIPrintf(viewer,"    rtol_0=%G, rtol_max=%G, threshold=%G\n",kctx->rtol_0,kctx->rtol_max,kctx->threshold);
113:         PetscViewerASCIIPrintf(viewer,"    gamma=%G, alpha=%G, alpha2=%G\n",kctx->gamma,kctx->alpha,kctx->alpha2);
114:       }
115:     }
116:   } else if (isstring) {
117:     SNESGetType(snes,&type);
118:     PetscViewerStringSPrintf(viewer," %-3.3s",type);
119:   }
120:   SNESGetKSP(snes,&ksp);
121:   PetscViewerASCIIPushTab(viewer);
122:   KSPView(ksp,viewer);
123:   PetscViewerASCIIPopTab(viewer);
124:   return(0);
125: }

127: /*
128:   We retain a list of functions that also take SNES command 
129:   line options. These are called at the end SNESSetFromOptions()
130: */
131: #define MAXSETFROMOPTIONS 5
132: static PetscInt numberofsetfromoptions;
133: static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES);

137: /*@C
138:   SNESAddOptionsChecker - Adds an additional function to check for SNES options.

140:   Not Collective

142:   Input Parameter:
143: . snescheck - function that checks for options

145:   Level: developer

147: .seealso: SNESSetFromOptions()
148: @*/
149: PetscErrorCode  SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES))
150: {
152:   if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
153:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %D allowed", MAXSETFROMOPTIONS);
154:   }
155:   othersetfromoptions[numberofsetfromoptions++] = snescheck;
156:   return(0);
157: }

161: /*@
162:    SNESSetFromOptions - Sets various SNES and KSP parameters from user options.

164:    Collective on SNES

166:    Input Parameter:
167: .  snes - the SNES context

169:    Options Database Keys:
170: +  -snes_type <type> - ls, tr, umls, umtr, test
171: .  -snes_stol - convergence tolerance in terms of the norm
172:                 of the change in the solution between steps
173: .  -snes_atol <abstol> - absolute tolerance of residual norm
174: .  -snes_rtol <rtol> - relative decrease in tolerance norm from initial
175: .  -snes_max_it <max_it> - maximum number of iterations
176: .  -snes_max_funcs <max_funcs> - maximum number of function evaluations
177: .  -snes_max_fail <max_fail> - maximum number of failures
178: .  -snes_trtol <trtol> - trust region tolerance
179: .  -snes_no_convergence_test - skip convergence test in nonlinear 
180:                                solver; hence iterations will continue until max_it
181:                                or some other criterion is reached. Saves expense
182:                                of convergence test
183: .  -snes_monitor <optional filename> - prints residual norm at each iteration. if no
184:                                        filename given prints to stdout
185: .  -snes_monitor_solution - plots solution at each iteration
186: .  -snes_monitor_residual - plots residual (not its norm) at each iteration
187: .  -snes_monitor_solution_update - plots update to solution at each iteration 
188: .  -snes_monitor_draw - plots residual norm at each iteration 
189: .  -snes_fd - use finite differences to compute Jacobian; very slow, only for testing
190: .  -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration
191: -  -snes_converged_reason - print the reason for convergence/divergence after each solve

193:     Options Database for Eisenstat-Walker method:
194: +  -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence
195: .  -snes_ksp_ew_version ver - version of  Eisenstat-Walker method
196: .  -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0
197: .  -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax
198: .  -snes_ksp_ew_gamma <gamma> - Sets gamma
199: .  -snes_ksp_ew_alpha <alpha> - Sets alpha
200: .  -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 
201: -  -snes_ksp_ew_threshold <threshold> - Sets threshold

203:    Notes:
204:    To see all options, run your program with the -help option or consult
205:    the users manual.

207:    Level: beginner

209: .keywords: SNES, nonlinear, set, options, database

211: .seealso: SNESSetOptionsPrefix()
212: @*/
213: PetscErrorCode  SNESSetFromOptions(SNES snes)
214: {
215:   PetscTruth              flg;
216:   PetscInt                i,indx;
217:   const char              *deft = SNESLS;
218:   const char              *convtests[] = {"default","skip"};
219:   SNESKSPEW               *kctx = NULL;
220:   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
221:   PetscViewerASCIIMonitor monviewer;
222:   PetscErrorCode          ierr;


227:   PetscOptionsBegin(((PetscObject)snes)->comm,((PetscObject)snes)->prefix,"Nonlinear solver (SNES) options","SNES");
228:     if (!SNESRegisterAllCalled) {SNESRegisterAll(PETSC_NULL);}
229:     if (((PetscObject)snes)->type_name) { deft = ((PetscObject)snes)->type_name; }
230:     PetscOptionsList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg);
231:     if (flg) {
232:       SNESSetType(snes,type);
233:     } else if (!((PetscObject)snes)->type_name) {
234:       SNESSetType(snes,deft);
235:     }
236:     PetscOptionsName("-snes_view","Print detailed information on solver used","SNESView",0);

238:     PetscOptionsReal("-snes_stol","Stop if step length less then","SNESSetTolerances",snes->xtol,&snes->xtol,0);
239:     PetscOptionsReal("-snes_atol","Stop if function norm less then","SNESSetTolerances",snes->abstol,&snes->abstol,0);

241:     PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less then","SNESSetTolerances",snes->rtol,&snes->rtol,0);
242:     PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,PETSC_NULL);
243:     PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,PETSC_NULL);
244:     PetscOptionsInt("-snes_max_fail","Maximum failures","SNESSetTolerances",snes->maxFailures,&snes->maxFailures,PETSC_NULL);

246:     PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,2,"default",&indx,&flg);
247:     if (flg) {
248:       switch (indx) {
249:       case 0: SNESSetConvergenceTest(snes,SNESDefaultConverged,PETSC_NULL); break;
250:       case 1: SNESSetConvergenceTest(snes,SNESSkipConverged,PETSC_NULL);    break;
251:       }
252:     }

254:     PetscOptionsName("-snes_converged_reason","Print reason for converged or diverged","SNESSolve",&flg);
255:     if (flg) {
256:       snes->printreason = PETSC_TRUE;
257:     }

259:     kctx = (SNESKSPEW *)snes->kspconvctx;

261:     PetscOptionsTruth("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,PETSC_NULL);

263:     PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,0);
264:     PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,0);
265:     PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,0);
266:     PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,0);
267:     PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,0);
268:     PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,0);
269:     PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,0);

271:     PetscOptionsName("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",&flg);
272:     if (flg) {SNESMonitorCancel(snes);}

274:     PetscOptionsString("-snes_monitor","Monitor norm of function","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
275:     if (flg) {
276:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
277:       SNESMonitorSet(snes,SNESMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
278:     }

280:     PetscOptionsString("-snes_ratiomonitor","Monitor ratios of norms of function","SNESMonitorSetRatio","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
281:     if (flg) {
282:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
283:       SNESMonitorSetRatio(snes,monviewer);
284:     }

286:     PetscOptionsString("-snes_monitor_short","Monitor norm of function (fewer digits)","SNESMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
287:     if (flg) {
288:       PetscViewerASCIIMonitorCreate(((PetscObject)snes)->comm,monfilename,0,&monviewer);
289:       SNESMonitorSet(snes,SNESMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
290:     }

292:     PetscOptionsName("-snes_monitor_solution","Plot solution at each iteration","SNESMonitorSolution",&flg);
293:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolution,0,0);}
294:     PetscOptionsName("-snes_monitor_solution_update","Plot correction at each iteration","SNESMonitorSolutionUpdate",&flg);
295:     if (flg) {SNESMonitorSet(snes,SNESMonitorSolutionUpdate,0,0);}
296:     PetscOptionsName("-snes_monitor_residual","Plot residual at each iteration","SNESMonitorResidual",&flg);
297:     if (flg) {SNESMonitorSet(snes,SNESMonitorResidual,0,0);}
298:     PetscOptionsName("-snes_monitor_draw","Plot function norm at each iteration","SNESMonitorLG",&flg);
299:     if (flg) {SNESMonitorSet(snes,SNESMonitorLG,PETSC_NULL,PETSC_NULL);}

301:     PetscOptionsName("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESDefaultComputeJacobian",&flg);
302:     if (flg) {
303:       SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESDefaultComputeJacobian,snes->funP);
304:       PetscInfo(snes,"Setting default finite difference Jacobian matrix\n");
305:     }

307:     for(i = 0; i < numberofsetfromoptions; i++) {
308:       (*othersetfromoptions[i])(snes);
309:     }

311:     if (snes->ops->setfromoptions) {
312:       (*snes->ops->setfromoptions)(snes);
313:     }
314:   PetscOptionsEnd();

316:   KSPSetFromOptions(snes->ksp);

318:   return(0);
319: }


324: /*@
325:    SNESSetApplicationContext - Sets the optional user-defined context for 
326:    the nonlinear solvers.  

328:    Collective on SNES

330:    Input Parameters:
331: +  snes - the SNES context
332: -  usrP - optional user context

334:    Level: intermediate

336: .keywords: SNES, nonlinear, set, application, context

338: .seealso: SNESGetApplicationContext()
339: @*/
340: PetscErrorCode  SNESSetApplicationContext(SNES snes,void *usrP)
341: {
344:   snes->user                = usrP;
345:   return(0);
346: }

350: /*@C
351:    SNESGetApplicationContext - Gets the user-defined context for the 
352:    nonlinear solvers.  

354:    Not Collective

356:    Input Parameter:
357: .  snes - SNES context

359:    Output Parameter:
360: .  usrP - user context

362:    Level: intermediate

364: .keywords: SNES, nonlinear, get, application, context

366: .seealso: SNESSetApplicationContext()
367: @*/
368: PetscErrorCode  SNESGetApplicationContext(SNES snes,void **usrP)
369: {
372:   *usrP = snes->user;
373:   return(0);
374: }

378: /*@
379:    SNESGetIterationNumber - Gets the number of nonlinear iterations completed
380:    at this time.

382:    Not Collective

384:    Input Parameter:
385: .  snes - SNES context

387:    Output Parameter:
388: .  iter - iteration number

390:    Notes:
391:    For example, during the computation of iteration 2 this would return 1.

393:    This is useful for using lagged Jacobians (where one does not recompute the 
394:    Jacobian at each SNES iteration). For example, the code
395: .vb
396:       SNESGetIterationNumber(snes,&it);
397:       if (!(it % 2)) {
398:         [compute Jacobian here]
399:       }
400: .ve
401:    can be used in your ComputeJacobian() function to cause the Jacobian to be
402:    recomputed every second SNES iteration.

404:    Level: intermediate

406: .keywords: SNES, nonlinear, get, iteration, number, 

408: .seealso:   SNESGetFunctionNorm(), SNESGetLinearSolveIterations()
409: @*/
410: PetscErrorCode  SNESGetIterationNumber(SNES snes,PetscInt* iter)
411: {
415:   *iter = snes->iter;
416:   return(0);
417: }

421: /*@
422:    SNESGetFunctionNorm - Gets the norm of the current function that was set
423:    with SNESSSetFunction().

425:    Collective on SNES

427:    Input Parameter:
428: .  snes - SNES context

430:    Output Parameter:
431: .  fnorm - 2-norm of function

433:    Level: intermediate

435: .keywords: SNES, nonlinear, get, function, norm

437: .seealso: SNESGetFunction(), SNESGetIterationNumber(), SNESGetLinearSolveIterations()
438: @*/
439: PetscErrorCode  SNESGetFunctionNorm(SNES snes,PetscReal *fnorm)
440: {
444:   *fnorm = snes->norm;
445:   return(0);
446: }

450: /*@
451:    SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps
452:    attempted by the nonlinear solver.

454:    Not Collective

456:    Input Parameter:
457: .  snes - SNES context

459:    Output Parameter:
460: .  nfails - number of unsuccessful steps attempted

462:    Notes:
463:    This counter is reset to zero for each successive call to SNESSolve().

465:    Level: intermediate

467: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

469: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
470:           SNESSetMaxNonlinearStepFailures(), SNESGetMaxNonlinearStepFailures()
471: @*/
472: PetscErrorCode  SNESGetNonlinearStepFailures(SNES snes,PetscInt* nfails)
473: {
477:   *nfails = snes->numFailures;
478:   return(0);
479: }

483: /*@
484:    SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps
485:    attempted by the nonlinear solver before it gives up.

487:    Not Collective

489:    Input Parameters:
490: +  snes     - SNES context
491: -  maxFails - maximum of unsuccessful steps

493:    Level: intermediate

495: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

497: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
498:           SNESGetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
499: @*/
500: PetscErrorCode  SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails)
501: {
504:   snes->maxFailures = maxFails;
505:   return(0);
506: }

510: /*@
511:    SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps
512:    attempted by the nonlinear solver before it gives up.

514:    Not Collective

516:    Input Parameter:
517: .  snes     - SNES context

519:    Output Parameter:
520: .  maxFails - maximum of unsuccessful steps

522:    Level: intermediate

524: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

526: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures(),
527:           SNESSetMaxNonlinearStepFailures(), SNESGetNonlinearStepFailures()
528:  
529: @*/
530: PetscErrorCode  SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails)
531: {
535:   *maxFails = snes->maxFailures;
536:   return(0);
537: }

541: /*@
542:    SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations
543:      done by SNES.

545:    Not Collective

547:    Input Parameter:
548: .  snes     - SNES context

550:    Output Parameter:
551: .  nfuncs - number of evaluations

553:    Level: intermediate

555: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

557: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(), SNESGetLinearSolveFailures()
558: @*/
559: PetscErrorCode  SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs)
560: {
564:   *nfuncs = snes->nfuncs;
565:   return(0);
566: }

570: /*@
571:    SNESGetLinearSolveFailures - Gets the number of failed (non-converged)
572:    linear solvers.

574:    Not Collective

576:    Input Parameter:
577: .  snes - SNES context

579:    Output Parameter:
580: .  nfails - number of failed solves

582:    Notes:
583:    This counter is reset to zero for each successive call to SNESSolve().

585:    Level: intermediate

587: .keywords: SNES, nonlinear, get, number, unsuccessful, steps

589: .seealso: SNESGetMaxLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures()
590: @*/
591: PetscErrorCode  SNESGetLinearSolveFailures(SNES snes,PetscInt* nfails)
592: {
596:   *nfails = snes->numLinearSolveFailures;
597:   return(0);
598: }

602: /*@
603:    SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts
604:    allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE

606:    Collective on SNES

608:    Input Parameters:
609: +  snes     - SNES context
610: -  maxFails - maximum allowed linear solve failures

612:    Level: intermediate

614:    Notes: By default this is 1; that is SNES returns on the first failed linear solve

616: .keywords: SNES, nonlinear, set, maximum, unsuccessful, steps

618: .seealso: SNESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures(), SNESGetLinearSolveIterations()
619: @*/
620: PetscErrorCode  SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails)
621: {
624:   snes->maxLinearSolveFailures = maxFails;
625:   return(0);
626: }

630: /*@
631:    SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that
632:      are allowed before SNES terminates

634:    Not Collective

636:    Input Parameter:
637: .  snes     - SNES context

639:    Output Parameter:
640: .  maxFails - maximum of unsuccessful solves allowed

642:    Level: intermediate

644:    Notes: By default this is 1; that is SNES returns on the first failed linear solve

646: .keywords: SNES, nonlinear, get, maximum, unsuccessful, steps

648: .seealso: SNESGetLinearSolveFailures(), SNESGetLinearSolverIterations(), SNESSetMaxLinearSolveFailures(),
649: @*/
650: PetscErrorCode  SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails)
651: {
655:   *maxFails = snes->maxLinearSolveFailures;
656:   return(0);
657: }

661: /*@
662:    SNESGetLinearSolveIterations - Gets the total number of linear iterations
663:    used by the nonlinear solver.

665:    Not Collective

667:    Input Parameter:
668: .  snes - SNES context

670:    Output Parameter:
671: .  lits - number of linear iterations

673:    Notes:
674:    This counter is reset to zero for each successive call to SNESSolve().

676:    Level: intermediate

678: .keywords: SNES, nonlinear, get, number, linear, iterations

680: .seealso:  SNESGetIterationNumber(), SNESGetFunctionNorm()S, NESGetLinearSolveFailures(), SNESGetMaxLinearSolveFailures()
681: @*/
682: PetscErrorCode  SNESGetLinearSolveIterations(SNES snes,PetscInt* lits)
683: {
687:   *lits = snes->linear_its;
688:   return(0);
689: }

693: /*@
694:    SNESGetKSP - Returns the KSP context for a SNES solver.

696:    Not Collective, but if SNES object is parallel, then KSP object is parallel

698:    Input Parameter:
699: .  snes - the SNES context

701:    Output Parameter:
702: .  ksp - the KSP context

704:    Notes:
705:    The user can then directly manipulate the KSP context to set various
706:    options, etc.  Likewise, the user can then extract and manipulate the 
707:    PC contexts as well.

709:    Level: beginner

711: .keywords: SNES, nonlinear, get, KSP, context

713: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
714: @*/
715: PetscErrorCode  SNESGetKSP(SNES snes,KSP *ksp)
716: {
720:   *ksp = snes->ksp;
721:   return(0);
722: }

726: /*@
727:    SNESSetKSP - Sets a KSP context for the SNES object to use

729:    Not Collective, but the SNES and KSP objects must live on the same MPI_Comm

731:    Input Parameters:
732: +  snes - the SNES context
733: -  ksp - the KSP context

735:    Notes:
736:    The SNES object already has its KSP object, you can obtain with SNESGetKSP()
737:    so this routine is rarely needed.

739:    The KSP object that is already in the SNES object has its reference count
740:    decreased by one.

742:    Level: developer

744: .keywords: SNES, nonlinear, get, KSP, context

746: .seealso: KSPGetPC(), SNESCreate(), KSPCreate(), SNESSetKSP()
747: @*/
748: PetscErrorCode  SNESSetKSP(SNES snes,KSP ksp)
749: {

756:   PetscObjectReference((PetscObject)ksp);
757:   if (snes->ksp) {PetscObjectDereference((PetscObject)snes->ksp);}
758:   snes->ksp = ksp;
759:   return(0);
760: }

762: #if 0
765: static PetscErrorCode SNESPublish_Petsc(PetscObject obj)
766: {
768:   return(0);
769: }
770: #endif

772: /* -----------------------------------------------------------*/
775: /*@
776:    SNESCreate - Creates a nonlinear solver context.

778:    Collective on MPI_Comm

780:    Input Parameters:
781: .  comm - MPI communicator

783:    Output Parameter:
784: .  outsnes - the new SNES context

786:    Options Database Keys:
787: +   -snes_mf - Activates default matrix-free Jacobian-vector products,
788:                and no preconditioning matrix
789: .   -snes_mf_operator - Activates default matrix-free Jacobian-vector
790:                products, and a user-provided preconditioning matrix
791:                as set by SNESSetJacobian()
792: -   -snes_fd - Uses (slow!) finite differences to compute Jacobian

794:    Level: beginner

796: .keywords: SNES, nonlinear, create, context

798: .seealso: SNESSolve(), SNESDestroy(), SNES
799: @*/
800: PetscErrorCode  SNESCreate(MPI_Comm comm,SNES *outsnes)
801: {
802:   PetscErrorCode      ierr;
803:   SNES                snes;
804:   SNESKSPEW           *kctx;

808:   *outsnes = PETSC_NULL;
809: #ifndef PETSC_USE_DYNAMIC_LIBRARIES
810:   SNESInitializePackage(PETSC_NULL);
811: #endif

813:   PetscHeaderCreate(snes,_p_SNES,struct _SNESOps,SNES_COOKIE,0,"SNES",comm,SNESDestroy,SNESView);

815:   snes->ops->converged    = SNESDefaultConverged;
816:   snes->max_its           = 50;
817:   snes->max_funcs          = 10000;
818:   snes->norm                  = 0.0;
819:   snes->rtol                  = 1.e-8;
820:   snes->ttol              = 0.0;
821:   snes->abstol                  = 1.e-50;
822:   snes->xtol                  = 1.e-8;
823:   snes->deltatol          = 1.e-12;
824:   snes->nfuncs            = 0;
825:   snes->numFailures       = 0;
826:   snes->maxFailures       = 1;
827:   snes->linear_its        = 0;
828:   snes->numbermonitors    = 0;
829:   snes->data              = 0;
830:   snes->setupcalled       = PETSC_FALSE;
831:   snes->ksp_ewconv        = PETSC_FALSE;
832:   snes->vwork             = 0;
833:   snes->nwork             = 0;
834:   snes->conv_hist_len     = 0;
835:   snes->conv_hist_max     = 0;
836:   snes->conv_hist         = PETSC_NULL;
837:   snes->conv_hist_its     = PETSC_NULL;
838:   snes->conv_hist_reset   = PETSC_TRUE;
839:   snes->reason            = SNES_CONVERGED_ITERATING;

841:   snes->numLinearSolveFailures = 0;
842:   snes->maxLinearSolveFailures = 1;

844:   /* Create context to compute Eisenstat-Walker relative tolerance for KSP */
845:   PetscNewLog(snes,SNESKSPEW,&kctx);
846:   snes->kspconvctx  = (void*)kctx;
847:   kctx->version     = 2;
848:   kctx->rtol_0      = .3; /* Eisenstat and Walker suggest rtol_0=.5, but 
849:                              this was too large for some test cases */
850:   kctx->rtol_last   = 0;
851:   kctx->rtol_max    = .9;
852:   kctx->gamma       = 1.0;
853:   kctx->alpha       = .5*(1.0 + sqrt(5.0));
854:   kctx->alpha2      = kctx->alpha;
855:   kctx->threshold   = .1;
856:   kctx->lresid_last = 0;
857:   kctx->norm_last   = 0;

859:   KSPCreate(comm,&snes->ksp);
860:   PetscLogObjectParent(snes,snes->ksp);

862:   *outsnes = snes;
863:   PetscPublishAll(snes);
864:   return(0);
865: }

869: /*@C
870:    SNESSetFunction - Sets the function evaluation routine and function 
871:    vector for use by the SNES routines in solving systems of nonlinear
872:    equations.

874:    Collective on SNES

876:    Input Parameters:
877: +  snes - the SNES context
878: .  r - vector to store function value
879: .  func - function evaluation routine
880: -  ctx - [optional] user-defined context for private data for the 
881:          function evaluation routine (may be PETSC_NULL)

883:    Calling sequence of func:
884: $    func (SNES snes,Vec x,Vec f,void *ctx);

886: .  f - function vector
887: -  ctx - optional user-defined function context 

889:    Notes:
890:    The Newton-like methods typically solve linear systems of the form
891: $      f'(x) x = -f(x),
892:    where f'(x) denotes the Jacobian matrix and f(x) is the function.

894:    Level: beginner

896: .keywords: SNES, nonlinear, set, function

898: .seealso: SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian()
899: @*/
900: PetscErrorCode  SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*func)(SNES,Vec,Vec,void*),void *ctx)
901: {
907:   PetscObjectReference((PetscObject)r);
908:   if (snes->vec_func) { VecDestroy(snes->vec_func); }
909:   snes->ops->computefunction = func;
910:   snes->vec_func             = r;
911:   snes->funP                 = ctx;
912:   return(0);
913: }

915: /* --------------------------------------------------------------- */
918: /*@C
919:    SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set
920:    it assumes a zero right hand side.

922:    Collective on SNES

924:    Input Parameter:
925: .  snes - the SNES context

927:    Output Parameter:
928: .  rhs - the right hand side vector or PETSC_NULL if the right hand side vector is null

930:    Level: intermediate

932: .keywords: SNES, nonlinear, get, function, right hand side

934: .seealso: SNESGetSolution(), SNESGetFunction(), SNESComputeFunction(), SNESSetJacobian(), SNESSetFunction()
935: @*/
936: PetscErrorCode  SNESGetRhs(SNES snes,Vec *rhs)
937: {
941:   *rhs = snes->vec_rhs;
942:   return(0);
943: }

947: /*@
948:    SNESComputeFunction - Calls the function that has been set with
949:                          SNESSetFunction().  

951:    Collective on SNES

953:    Input Parameters:
954: +  snes - the SNES context
955: -  x - input vector

957:    Output Parameter:
958: .  y - function vector, as set by SNESSetFunction()

960:    Notes:
961:    SNESComputeFunction() is typically used within nonlinear solvers
962:    implementations, so most users would not generally call this routine
963:    themselves.

965:    Level: developer

967: .keywords: SNES, nonlinear, compute, function

969: .seealso: SNESSetFunction(), SNESGetFunction()
970: @*/
971: PetscErrorCode  SNESComputeFunction(SNES snes,Vec x,Vec y)
972: {


983:   if (snes->ops->computefunction) {
984:     PetscStackPush("SNES user function");
985:     CHKMEMQ;
986:     (*snes->ops->computefunction)(snes,x,y,snes->funP);
987:     CHKMEMQ;
988:     PetscStackPop;
989:     if (PetscExceptionValue(ierr)) {
991:     }
992: 
993:   } else if (snes->vec_rhs) {
994:     MatMult(snes->jacobian, x, y);
995:   } else {
996:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() before SNESComputeFunction(), likely called from SNESSolve().");
997:   }
998:   if (snes->vec_rhs) {
999:     VecAXPY(y,-1.0,snes->vec_rhs);
1000:   }
1001:   snes->nfuncs++;
1003:   return(0);
1004: }

1008: /*@
1009:    SNESComputeJacobian - Computes the Jacobian matrix that has been
1010:    set with SNESSetJacobian().

1012:    Collective on SNES and Mat

1014:    Input Parameters:
1015: +  snes - the SNES context
1016: -  x - input vector

1018:    Output Parameters:
1019: +  A - Jacobian matrix
1020: .  B - optional preconditioning matrix
1021: -  flag - flag indicating matrix structure (one of, SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER)

1023:    Notes: 
1024:    Most users should not need to explicitly call this routine, as it 
1025:    is used internally within the nonlinear solvers. 

1027:    See KSPSetOperators() for important information about setting the
1028:    flag parameter.

1030:    Level: developer

1032: .keywords: SNES, compute, Jacobian, matrix

1034: .seealso:  SNESSetJacobian(), KSPSetOperators(), MatStructure
1035: @*/
1036: PetscErrorCode  SNESComputeJacobian(SNES snes,Vec X,Mat *A,Mat *B,MatStructure *flg)
1037: {

1045:   if (!snes->ops->computejacobian) return(0);
1047:   *flg = DIFFERENT_NONZERO_PATTERN;
1048:   PetscStackPush("SNES user Jacobian function");
1049:   CHKMEMQ;
1050:   (*snes->ops->computejacobian)(snes,X,A,B,flg,snes->jacP);
1051:   CHKMEMQ;
1052:   PetscStackPop;
1054:   /* make sure user returned a correct Jacobian and preconditioner */
1057:   return(0);
1058: }

1062: /*@C
1063:    SNESSetJacobian - Sets the function to compute Jacobian as well as the
1064:    location to store the matrix.

1066:    Collective on SNES and Mat

1068:    Input Parameters:
1069: +  snes - the SNES context
1070: .  A - Jacobian matrix
1071: .  B - preconditioner matrix (usually same as the Jacobian)
1072: .  func - Jacobian evaluation routine
1073: -  ctx - [optional] user-defined context for private data for the 
1074:          Jacobian evaluation routine (may be PETSC_NULL)

1076:    Calling sequence of func:
1077: $     func (SNES snes,Vec x,Mat *A,Mat *B,int *flag,void *ctx);

1079: +  x - input vector
1080: .  A - Jacobian matrix
1081: .  B - preconditioner matrix, usually the same as A
1082: .  flag - flag indicating information about the preconditioner matrix
1083:    structure (same as flag in KSPSetOperators()), one of SAME_NONZERO_PATTERN,DIFFERENT_NONZERO_PATTERN,SAME_PRECONDITIONER
1084: -  ctx - [optional] user-defined Jacobian context

1086:    Notes: 
1087:    See KSPSetOperators() for important information about setting the flag
1088:    output parameter in the routine func().  Be sure to read this information!

1090:    The routine func() takes Mat * as the matrix arguments rather than Mat.  
1091:    This allows the Jacobian evaluation routine to replace A and/or B with a 
1092:    completely new new matrix structure (not just different matrix elements)
1093:    when appropriate, for instance, if the nonzero structure is changing
1094:    throughout the global iterations.

1096:    Level: beginner

1098: .keywords: SNES, nonlinear, set, Jacobian, matrix

1100: .seealso: KSPSetOperators(), SNESSetFunction(), MatMFFDComputeJacobian(), SNESDefaultComputeJacobianColor(), MatStructure
1101: @*/
1102: PetscErrorCode  SNESSetJacobian(SNES snes,Mat A,Mat B,PetscErrorCode (*func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void *ctx)
1103: {

1112:   if (func) snes->ops->computejacobian = func;
1113:   if (ctx)  snes->jacP                 = ctx;
1114:   if (A) {
1115:     PetscObjectReference((PetscObject)A);
1116:     if (snes->jacobian) {MatDestroy(snes->jacobian);}
1117:     snes->jacobian = A;
1118:   }
1119:   if (B) {
1120:     PetscObjectReference((PetscObject)B);
1121:     if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1122:     snes->jacobian_pre = B;
1123:   }
1124:   return(0);
1125: }

1129: /*@C
1130:    SNESGetJacobian - Returns the Jacobian matrix and optionally the user 
1131:    provided context for evaluating the Jacobian.

1133:    Not Collective, but Mat object will be parallel if SNES object is

1135:    Input Parameter:
1136: .  snes - the nonlinear solver context

1138:    Output Parameters:
1139: +  A - location to stash Jacobian matrix (or PETSC_NULL)
1140: .  B - location to stash preconditioner matrix (or PETSC_NULL)
1141: .  func - location to put Jacobian function (or PETSC_NULL)
1142: -  ctx - location to stash Jacobian ctx (or PETSC_NULL)

1144:    Level: advanced

1146: .seealso: SNESSetJacobian(), SNESComputeJacobian()
1147: @*/
1148: PetscErrorCode  SNESGetJacobian(SNES snes,Mat *A,Mat *B,PetscErrorCode (**func)(SNES,Vec,Mat*,Mat*,MatStructure*,void*),void **ctx)
1149: {
1152:   if (A)    *A    = snes->jacobian;
1153:   if (B)    *B    = snes->jacobian_pre;
1154:   if (func) *func = snes->ops->computejacobian;
1155:   if (ctx)  *ctx  = snes->jacP;
1156:   return(0);
1157: }

1159: /* ----- Routines to initialize and destroy a nonlinear solver ---- */
1160: EXTERN PetscErrorCode  SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*);

1164: /*@
1165:    SNESSetUp - Sets up the internal data structures for the later use
1166:    of a nonlinear solver.

1168:    Collective on SNES

1170:    Input Parameters:
1171: .  snes - the SNES context

1173:    Notes:
1174:    For basic use of the SNES solvers the user need not explicitly call
1175:    SNESSetUp(), since these actions will automatically occur during
1176:    the call to SNESSolve().  However, if one wishes to control this
1177:    phase separately, SNESSetUp() should be called after SNESCreate()
1178:    and optional routines of the form SNESSetXXX(), but before SNESSolve().  

1180:    Level: advanced

1182: .keywords: SNES, nonlinear, setup

1184: .seealso: SNESCreate(), SNESSolve(), SNESDestroy()
1185: @*/
1186: PetscErrorCode  SNESSetUp(SNES snes)
1187: {
1189:   PetscTruth     flg;

1193:   if (snes->setupcalled) return(0);

1195:   if (!((PetscObject)snes)->type_name) {
1196:     SNESSetType(snes,SNESLS);
1197:   }

1199:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator",&flg);
1200:   /*
1201:       This version replaces the user provided Jacobian matrix with a
1202:       matrix-free version but still employs the user-provided preconditioner matrix
1203:   */
1204:   if (flg) {
1205:     Mat J;
1206:     MatCreateSNESMF(snes,&J);
1207:     MatMFFDSetFromOptions(J);
1208:     PetscInfo(snes,"Setting default matrix-free operator routines\n");
1209:     SNESSetJacobian(snes,J,0,0,0);
1210:     MatDestroy(J);
1211:   }

1213: #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_MAT_SINGLE) && !defined(PETSC_USE_LONG_DOUBLE) && !defined(PETSC_USE_INT)
1214:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf_operator2",&flg);
1215:   if (flg) {
1216:     Mat J;
1217:     SNESDefaultMatrixFreeCreate2(snes,snes->vec_sol,&J);
1218:     PetscInfo(snes,"Setting default matrix-free operator routines (version 2)\n");
1219:     SNESSetJacobian(snes,J,0,0,0);
1220:     MatDestroy(J);
1221:   }
1222: #endif

1224:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_mf",&flg);
1225:   /*
1226:       This version replaces both the user-provided Jacobian and the user-
1227:       provided preconditioner matrix with the default matrix free version.
1228:    */
1229:   if (flg) {
1230:     Mat  J;
1231:     KSP ksp;
1232:     PC   pc;
1233:     /* create and set matrix-free operator */
1234:     MatCreateSNESMF(snes,&J);
1235:     MatMFFDSetFromOptions(J);
1236:     PetscInfo(snes,"Setting default matrix-free operator routines\n");
1237:     SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,snes->funP);
1238:     MatDestroy(J);
1239:     /* force no preconditioner */
1240:     SNESGetKSP(snes,&ksp);
1241:     KSPGetPC(ksp,&pc);
1242:     PetscTypeCompare((PetscObject)pc,PCSHELL,&flg);
1243:     if (!flg) {
1244:       PetscInfo(snes,"Setting default matrix-free preconditioner routines;\nThat is no preconditioner is being used\n");
1245:       PCSetType(pc,PCNONE);
1246:     }
1247:   }

1249:   if (!snes->vec_func && !snes->vec_rhs) {
1250:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1251:   }
1252:   if (!snes->ops->computefunction && !snes->vec_rhs) {
1253:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetFunction() first");
1254:   }
1255:   if (!snes->jacobian) {
1256:     SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Must call SNESSetJacobian() first \n or use -snes_mf option");
1257:   }
1258:   if (snes->vec_func == snes->vec_sol) {
1259:     SETERRQ(PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector");
1260:   }
1261: 
1262:   if (snes->ops->setup) {
1263:     (*snes->ops->setup)(snes);
1264:   }
1265:   snes->setupcalled = PETSC_TRUE;
1266:   return(0);
1267: }

1271: /*@
1272:    SNESDestroy - Destroys the nonlinear solver context that was created
1273:    with SNESCreate().

1275:    Collective on SNES

1277:    Input Parameter:
1278: .  snes - the SNES context

1280:    Level: beginner

1282: .keywords: SNES, nonlinear, destroy

1284: .seealso: SNESCreate(), SNESSolve()
1285: @*/
1286: PetscErrorCode  SNESDestroy(SNES snes)
1287: {

1292:   if (--((PetscObject)snes)->refct > 0) return(0);

1294:   /* if memory was published with AMS then destroy it */
1295:   PetscObjectDepublish(snes);
1296:   if (snes->ops->destroy) {(*(snes)->ops->destroy)(snes);}
1297: 
1298:   if (snes->vec_rhs) {VecDestroy(snes->vec_rhs);}
1299:   if (snes->vec_sol) {VecDestroy(snes->vec_sol);}
1300:   if (snes->vec_func) {VecDestroy(snes->vec_func);}
1301:   if (snes->jacobian) {MatDestroy(snes->jacobian);}
1302:   if (snes->jacobian_pre) {MatDestroy(snes->jacobian_pre);}
1303:   KSPDestroy(snes->ksp);
1304:   PetscFree(snes->kspconvctx);
1305:   if (snes->vwork) {VecDestroyVecs(snes->vwork,snes->nvwork);}
1306:   SNESMonitorCancel(snes);
1307:   PetscHeaderDestroy(snes);
1308:   return(0);
1309: }

1311: /* ----------- Routines to set solver parameters ---------- */

1315: /*@
1316:    SNESSetTolerances - Sets various parameters used in convergence tests.

1318:    Collective on SNES

1320:    Input Parameters:
1321: +  snes - the SNES context
1322: .  abstol - absolute convergence tolerance
1323: .  rtol - relative convergence tolerance
1324: .  stol -  convergence tolerance in terms of the norm
1325:            of the change in the solution between steps
1326: .  maxit - maximum number of iterations
1327: -  maxf - maximum number of function evaluations

1329:    Options Database Keys: 
1330: +    -snes_atol <abstol> - Sets abstol
1331: .    -snes_rtol <rtol> - Sets rtol
1332: .    -snes_stol <stol> - Sets stol
1333: .    -snes_max_it <maxit> - Sets maxit
1334: -    -snes_max_funcs <maxf> - Sets maxf

1336:    Notes:
1337:    The default maximum number of iterations is 50.
1338:    The default maximum number of function evaluations is 1000.

1340:    Level: intermediate

1342: .keywords: SNES, nonlinear, set, convergence, tolerances

1344: .seealso: SNESSetTrustRegionTolerance()
1345: @*/
1346: PetscErrorCode  SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf)
1347: {
1350:   if (abstol != PETSC_DEFAULT)  snes->abstol      = abstol;
1351:   if (rtol != PETSC_DEFAULT)  snes->rtol      = rtol;
1352:   if (stol != PETSC_DEFAULT)  snes->xtol      = stol;
1353:   if (maxit != PETSC_DEFAULT) snes->max_its   = maxit;
1354:   if (maxf != PETSC_DEFAULT)  snes->max_funcs = maxf;
1355:   return(0);
1356: }

1360: /*@
1361:    SNESGetTolerances - Gets various parameters used in convergence tests.

1363:    Not Collective

1365:    Input Parameters:
1366: +  snes - the SNES context
1367: .  atol - absolute convergence tolerance
1368: .  rtol - relative convergence tolerance
1369: .  stol -  convergence tolerance in terms of the norm
1370:            of the change in the solution between steps
1371: .  maxit - maximum number of iterations
1372: -  maxf - maximum number of function evaluations

1374:    Notes:
1375:    The user can specify PETSC_NULL for any parameter that is not needed.

1377:    Level: intermediate

1379: .keywords: SNES, nonlinear, get, convergence, tolerances

1381: .seealso: SNESSetTolerances()
1382: @*/
1383: PetscErrorCode  SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf)
1384: {
1387:   if (atol)  *atol  = snes->abstol;
1388:   if (rtol)  *rtol  = snes->rtol;
1389:   if (stol)  *stol  = snes->xtol;
1390:   if (maxit) *maxit = snes->max_its;
1391:   if (maxf)  *maxf  = snes->max_funcs;
1392:   return(0);
1393: }

1397: /*@
1398:    SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance.  

1400:    Collective on SNES

1402:    Input Parameters:
1403: +  snes - the SNES context
1404: -  tol - tolerance
1405:    
1406:    Options Database Key: 
1407: .  -snes_trtol <tol> - Sets tol

1409:    Level: intermediate

1411: .keywords: SNES, nonlinear, set, trust region, tolerance

1413: .seealso: SNESSetTolerances()
1414: @*/
1415: PetscErrorCode  SNESSetTrustRegionTolerance(SNES snes,PetscReal tol)
1416: {
1419:   snes->deltatol = tol;
1420:   return(0);
1421: }

1423: /* 
1424:    Duplicate the lg monitors for SNES from KSP; for some reason with 
1425:    dynamic libraries things don't work under Sun4 if we just use 
1426:    macros instead of functions
1427: */
1430: PetscErrorCode  SNESMonitorLG(SNES snes,PetscInt it,PetscReal norm,void *ctx)
1431: {

1436:   KSPMonitorLG((KSP)snes,it,norm,ctx);
1437:   return(0);
1438: }

1442: PetscErrorCode  SNESMonitorLGCreate(const char host[],const char label[],int x,int y,int m,int n,PetscDrawLG *draw)
1443: {

1447:   KSPMonitorLGCreate(host,label,x,y,m,n,draw);
1448:   return(0);
1449: }

1453: PetscErrorCode  SNESMonitorLGDestroy(PetscDrawLG draw)
1454: {

1458:   KSPMonitorLGDestroy(draw);
1459:   return(0);
1460: }

1462: /* ------------ Routines to set performance monitoring options ----------- */

1466: /*@C
1467:    SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every
1468:    iteration of the nonlinear solver to display the iteration's 
1469:    progress.   

1471:    Collective on SNES

1473:    Input Parameters:
1474: +  snes - the SNES context
1475: .  func - monitoring routine
1476: .  mctx - [optional] user-defined context for private data for the 
1477:           monitor routine (use PETSC_NULL if no context is desired)
1478: -  monitordestroy - [optional] routine that frees monitor context
1479:           (may be PETSC_NULL)

1481:    Calling sequence of func:
1482: $     int func(SNES snes,PetscInt its, PetscReal norm,void *mctx)

1484: +    snes - the SNES context
1485: .    its - iteration number
1486: .    norm - 2-norm function value (may be estimated)
1487: -    mctx - [optional] monitoring context

1489:    Options Database Keys:
1490: +    -snes_monitor        - sets SNESMonitorDefault()
1491: .    -snes_monitor_draw    - sets line graph monitor,
1492:                             uses SNESMonitorLGCreate()
1493: _    -snes_monitor_cancel - cancels all monitors that have
1494:                             been hardwired into a code by 
1495:                             calls to SNESMonitorSet(), but
1496:                             does not cancel those set via
1497:                             the options database.

1499:    Notes: 
1500:    Several different monitoring routines may be set by calling
1501:    SNESMonitorSet() multiple times; all will be called in the 
1502:    order in which they were set.

1504:    Level: intermediate

1506: .keywords: SNES, nonlinear, set, monitor

1508: .seealso: SNESMonitorDefault(), SNESMonitorCancel()
1509: @*/
1510: PetscErrorCode  SNESMonitorSet(SNES snes,PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void*))
1511: {
1512:   PetscInt i;

1516:   if (snes->numbermonitors >= MAXSNESMONITORS) {
1517:     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set");
1518:   }
1519:   for (i=0; i<snes->numbermonitors;i++) {
1520:     if (monitor == snes->monitor[i] && monitordestroy == snes->monitordestroy[i] && mctx == snes->monitorcontext[i]) return(0);

1522:     /* check if both default monitors that share common ASCII viewer */
1523:     if (monitor == snes->monitor[i] && monitor == SNESMonitorDefault) {
1524:       if (mctx && snes->monitorcontext[i]) {
1525:         PetscErrorCode          ierr;
1526:         PetscViewerASCIIMonitor viewer1 = (PetscViewerASCIIMonitor) mctx;
1527:         PetscViewerASCIIMonitor viewer2 = (PetscViewerASCIIMonitor) snes->monitorcontext[i];
1528:         if (viewer1->viewer == viewer2->viewer) {
1529:           (*monitordestroy)(mctx);
1530:           return(0);
1531:         }
1532:       }
1533:     }
1534:   }
1535:   snes->monitor[snes->numbermonitors]           = monitor;
1536:   snes->monitordestroy[snes->numbermonitors]    = monitordestroy;
1537:   snes->monitorcontext[snes->numbermonitors++]  = (void*)mctx;
1538:   return(0);
1539: }

1543: /*@C
1544:    SNESMonitorCancel - Clears all the monitor functions for a SNES object.

1546:    Collective on SNES

1548:    Input Parameters:
1549: .  snes - the SNES context

1551:    Options Database Key:
1552: .  -snes_monitor_cancel - cancels all monitors that have been hardwired
1553:     into a code by calls to SNESMonitorSet(), but does not cancel those 
1554:     set via the options database

1556:    Notes: 
1557:    There is no way to clear one specific monitor from a SNES object.

1559:    Level: intermediate

1561: .keywords: SNES, nonlinear, set, monitor

1563: .seealso: SNESMonitorDefault(), SNESMonitorSet()
1564: @*/
1565: PetscErrorCode  SNESMonitorCancel(SNES snes)
1566: {
1568:   PetscInt       i;

1572:   for (i=0; i<snes->numbermonitors; i++) {
1573:     if (snes->monitordestroy[i]) {
1574:       (*snes->monitordestroy[i])(snes->monitorcontext[i]);
1575:     }
1576:   }
1577:   snes->numbermonitors = 0;
1578:   return(0);
1579: }

1583: /*@C
1584:    SNESSetConvergenceTest - Sets the function that is to be used 
1585:    to test for convergence of the nonlinear iterative solution.   

1587:    Collective on SNES

1589:    Input Parameters:
1590: +  snes - the SNES context
1591: .  func - routine to test for convergence
1592: -  cctx - [optional] context for private data for the convergence routine 
1593:           (may be PETSC_NULL)

1595:    Calling sequence of func:
1596: $     PetscErrorCode func (SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx)

1598: +    snes - the SNES context
1599: .    it - current iteration (0 is the first and is before any Newton step)
1600: .    cctx - [optional] convergence context
1601: .    reason - reason for convergence/divergence
1602: .    xnorm - 2-norm of current iterate
1603: .    gnorm - 2-norm of current step
1604: -    f - 2-norm of function

1606:    Level: advanced

1608: .keywords: SNES, nonlinear, set, convergence, test

1610: .seealso: SNESDefaultConverged(), SNESSkipConverged()
1611: @*/
1612: PetscErrorCode  SNESSetConvergenceTest(SNES snes,PetscErrorCode (*func)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx)
1613: {
1616:   if (!func) func = SNESSkipConverged;
1617:   snes->ops->converged = func;
1618:   snes->cnvP           = cctx;
1619:   return(0);
1620: }

1624: /*@
1625:    SNESGetConvergedReason - Gets the reason the SNES iteration was stopped.

1627:    Not Collective

1629:    Input Parameter:
1630: .  snes - the SNES context

1632:    Output Parameter:
1633: .  reason - negative value indicates diverged, positive value converged, see petscsnes.h or the 
1634:             manual pages for the individual convergence tests for complete lists

1636:    Level: intermediate

1638:    Notes: Can only be called after the call the SNESSolve() is complete.

1640: .keywords: SNES, nonlinear, set, convergence, test

1642: .seealso: SNESSetConvergenceTest(), SNESConvergedReason
1643: @*/
1644: PetscErrorCode  SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason)
1645: {
1649:   *reason = snes->reason;
1650:   return(0);
1651: }

1655: /*@
1656:    SNESSetConvergenceHistory - Sets the array used to hold the convergence history.

1658:    Collective on SNES

1660:    Input Parameters:
1661: +  snes - iterative context obtained from SNESCreate()
1662: .  a   - array to hold history
1663: .  its - integer array holds the number of linear iterations for each solve.
1664: .  na  - size of a and its
1665: -  reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero,
1666:            else it continues storing new values for new nonlinear solves after the old ones

1668:    Notes:
1669:    If set, this array will contain the function norms computed
1670:    at each step.

1672:    This routine is useful, e.g., when running a code for purposes
1673:    of accurate performance monitoring, when no I/O should be done
1674:    during the section of code that is being timed.

1676:    Level: intermediate

1678: .keywords: SNES, set, convergence, history

1680: .seealso: SNESGetConvergenceHistory()

1682: @*/
1683: PetscErrorCode  SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscTruth reset)
1684: {
1689:   snes->conv_hist       = a;
1690:   snes->conv_hist_its   = its;
1691:   snes->conv_hist_max   = na;
1692:   snes->conv_hist_reset = reset;
1693:   return(0);
1694: }

1698: /*@C
1699:    SNESGetConvergenceHistory - Gets the array used to hold the convergence history.

1701:    Collective on SNES

1703:    Input Parameter:
1704: .  snes - iterative context obtained from SNESCreate()

1706:    Output Parameters:
1707: .  a   - array to hold history
1708: .  its - integer array holds the number of linear iterations (or
1709:          negative if not converged) for each solve.
1710: -  na  - size of a and its

1712:    Notes:
1713:     The calling sequence for this routine in Fortran is
1714: $   call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr)

1716:    This routine is useful, e.g., when running a code for purposes
1717:    of accurate performance monitoring, when no I/O should be done
1718:    during the section of code that is being timed.

1720:    Level: intermediate

1722: .keywords: SNES, get, convergence, history

1724: .seealso: SNESSetConvergencHistory()

1726: @*/
1727: PetscErrorCode  SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na)
1728: {
1731:   if (a)   *a   = snes->conv_hist;
1732:   if (its) *its = snes->conv_hist_its;
1733:   if (na)  *na  = snes->conv_hist_len;
1734:   return(0);
1735: }

1739: /*@C
1740:   SNESSetUpdate - Sets the general-purpose update function called
1741:   at the beginning o every iteration of the nonlinear solve. Specifically
1742:   it is called just before the Jacobian is "evaluated".

1744:   Collective on SNES

1746:   Input Parameters:
1747: . snes - The nonlinear solver context
1748: . func - The function

1750:   Calling sequence of func:
1751: . func (SNES snes, PetscInt step);

1753: . step - The current step of the iteration

1755:   Level: intermediate

1757: .keywords: SNES, update

1759: .seealso SNESDefaultUpdate(), SNESSetJacobian(), SNESSolve()
1760: @*/
1761: PetscErrorCode  SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt))
1762: {
1765:   snes->ops->update = func;
1766:   return(0);
1767: }

1771: /*@
1772:   SNESDefaultUpdate - The default update function which does nothing.

1774:   Not collective

1776:   Input Parameters:
1777: . snes - The nonlinear solver context
1778: . step - The current step of the iteration

1780:   Level: intermediate

1782: .keywords: SNES, update
1783: .seealso SNESSetUpdate(), SNESDefaultRhsBC(), SNESDefaultShortolutionBC()
1784: @*/
1785: PetscErrorCode  SNESDefaultUpdate(SNES snes, PetscInt step)
1786: {
1788:   return(0);
1789: }

1793: /*
1794:    SNESScaleStep_Private - Scales a step so that its length is less than the
1795:    positive parameter delta.

1797:     Input Parameters:
1798: +   snes - the SNES context
1799: .   y - approximate solution of linear system
1800: .   fnorm - 2-norm of current function
1801: -   delta - trust region size

1803:     Output Parameters:
1804: +   gpnorm - predicted function norm at the new point, assuming local 
1805:     linearization.  The value is zero if the step lies within the trust 
1806:     region, and exceeds zero otherwise.
1807: -   ynorm - 2-norm of the step

1809:     Note:
1810:     For non-trust region methods such as SNESLS, the parameter delta 
1811:     is set to be the maximum allowable step size.  

1813: .keywords: SNES, nonlinear, scale, step
1814: */
1815: PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm)
1816: {
1817:   PetscReal      nrm;
1818:   PetscScalar    cnorm;


1826:   VecNorm(y,NORM_2,&nrm);
1827:   if (nrm > *delta) {
1828:      nrm = *delta/nrm;
1829:      *gpnorm = (1.0 - nrm)*(*fnorm);
1830:      cnorm = nrm;
1831:      VecScale(y,cnorm);
1832:      *ynorm = *delta;
1833:   } else {
1834:      *gpnorm = 0.0;
1835:      *ynorm = nrm;
1836:   }
1837:   return(0);
1838: }

1842: /*@C
1843:    SNESSolve - Solves a nonlinear system F(x) = b.
1844:    Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX().

1846:    Collective on SNES

1848:    Input Parameters:
1849: +  snes - the SNES context
1850: .  b - the constant part of the equation, or PETSC_NULL to use zero.
1851: -  x - the solution vector.

1853:    Notes:
1854:    The user should initialize the vector,x, with the initial guess
1855:    for the nonlinear solve prior to calling SNESSolve.  In particular,
1856:    to employ an initial guess of zero, the user should explicitly set
1857:    this vector to zero by calling VecSet().

1859:    Level: beginner

1861: .keywords: SNES, nonlinear, solve

1863: .seealso: SNESCreate(), SNESDestroy(), SNESSetFunction(), SNESSetJacobian()
1864: @*/
1865: PetscErrorCode  SNESSolve(SNES snes,Vec b,Vec x)
1866: {
1868:   PetscTruth     flg;
1869:   char           filename[PETSC_MAX_PATH_LEN];
1870:   PetscViewer    viewer;


1879:   /* set solution vector */
1880:   PetscObjectReference((PetscObject)x);
1881:   if (snes->vec_sol) { VecDestroy(snes->vec_sol); }
1882:   snes->vec_sol = x;
1883:   /* set afine vector if provided */
1884:   if (b) { PetscObjectReference((PetscObject)b); }
1885:   if (snes->vec_rhs) { VecDestroy(snes->vec_rhs); }
1886:   snes->vec_rhs = b;
1887: 
1888:   if (!snes->vec_func && snes->vec_rhs) {
1889:     VecDuplicate(b, &snes->vec_func);
1890:   }

1892:   SNESSetUp(snes);

1894:   if (snes->conv_hist_reset) snes->conv_hist_len = 0;
1895:   snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;

1898:   (*snes->ops->solve)(snes);
1900:   if (snes->domainerror){
1901:     snes->reason      = SNES_DIVERGED_FUNCTION_DOMAIN;
1902:     snes->domainerror = PETSC_FALSE;
1903:   }

1905:   if (!snes->reason) {
1906:     SETERRQ(PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason");
1907:   }
1908: 
1909:   PetscOptionsGetString(((PetscObject)snes)->prefix,"-snes_view",filename,PETSC_MAX_PATH_LEN,&flg);
1910:   if (flg && !PetscPreLoadingOn) {
1911:     PetscViewerASCIIOpen(((PetscObject)snes)->comm,filename,&viewer);
1912:     SNESView(snes,viewer);
1913:     PetscViewerDestroy(viewer);
1914:   }

1916:   PetscOptionsHasName(((PetscObject)snes)->prefix,"-snes_test_local_min",&flg);
1917:   if (flg && !PetscPreLoadingOn) { SNESTestLocalMin(snes); }
1918:   if (snes->printreason) {
1919:     if (snes->reason > 0) {
1920:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve converged due to %s\n",SNESConvergedReasons[snes->reason]);
1921:     } else {
1922:       PetscPrintf(((PetscObject)snes)->comm,"Nonlinear solve did not converge due to %s\n",SNESConvergedReasons[snes->reason]);
1923:     }
1924:   }

1926:   return(0);
1927: }

1929: /* --------- Internal routines for SNES Package --------- */

1933: /*@C
1934:    SNESSetType - Sets the method for the nonlinear solver.  

1936:    Collective on SNES

1938:    Input Parameters:
1939: +  snes - the SNES context
1940: -  type - a known method

1942:    Options Database Key:
1943: .  -snes_type <type> - Sets the method; use -help for a list
1944:    of available methods (for instance, ls or tr)

1946:    Notes:
1947:    See "petsc/include/petscsnes.h" for available methods (for instance)
1948: +    SNESLS - Newton's method with line search
1949:      (systems of nonlinear equations)
1950: .    SNESTR - Newton's method with trust region
1951:      (systems of nonlinear equations)

1953:   Normally, it is best to use the SNESSetFromOptions() command and then
1954:   set the SNES solver type from the options database rather than by using
1955:   this routine.  Using the options database provides the user with
1956:   maximum flexibility in evaluating the many nonlinear solvers.
1957:   The SNESSetType() routine is provided for those situations where it
1958:   is necessary to set the nonlinear solver independently of the command
1959:   line or options database.  This might be the case, for example, when
1960:   the choice of solver changes during the execution of the program,
1961:   and the user's application is taking responsibility for choosing the
1962:   appropriate method.

1964:   Level: intermediate

1966: .keywords: SNES, set, type

1968: .seealso: SNESType, SNESCreate()

1970: @*/
1971: PetscErrorCode  SNESSetType(SNES snes,SNESType type)
1972: {
1973:   PetscErrorCode ierr,(*r)(SNES);
1974:   PetscTruth     match;


1980:   PetscTypeCompare((PetscObject)snes,type,&match);
1981:   if (match) return(0);

1983:    PetscFListFind(SNESList,((PetscObject)snes)->comm,type,(void (**)(void)) &r);
1984:   if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type);
1985:   /* Destroy the previous private SNES context */
1986:   if (snes->ops->destroy) { (*(snes)->ops->destroy)(snes); }
1987:   /* Reinitialize function pointers in SNESOps structure */
1988:   snes->ops->setup          = 0;
1989:   snes->ops->solve          = 0;
1990:   snes->ops->view           = 0;
1991:   snes->ops->setfromoptions = 0;
1992:   snes->ops->destroy        = 0;
1993:   /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */
1994:   snes->setupcalled = PETSC_FALSE;
1995:   (*r)(snes);
1996:   PetscObjectChangeTypeName((PetscObject)snes,type);
1997:   return(0);
1998: }


2001: /* --------------------------------------------------------------------- */
2004: /*@
2005:    SNESRegisterDestroy - Frees the list of nonlinear solvers that were
2006:    registered by SNESRegisterDynamic().

2008:    Not Collective

2010:    Level: advanced

2012: .keywords: SNES, nonlinear, register, destroy

2014: .seealso: SNESRegisterAll(), SNESRegisterAll()
2015: @*/
2016: PetscErrorCode  SNESRegisterDestroy(void)
2017: {

2021:   PetscFListDestroy(&SNESList);
2022:   SNESRegisterAllCalled = PETSC_FALSE;
2023:   return(0);
2024: }

2028: /*@C
2029:    SNESGetType - Gets the SNES method type and name (as a string).

2031:    Not Collective

2033:    Input Parameter:
2034: .  snes - nonlinear solver context

2036:    Output Parameter:
2037: .  type - SNES method (a character string)

2039:    Level: intermediate

2041: .keywords: SNES, nonlinear, get, type, name
2042: @*/
2043: PetscErrorCode  SNESGetType(SNES snes,SNESType *type)
2044: {
2048:   *type = ((PetscObject)snes)->type_name;
2049:   return(0);
2050: }

2054: /*@
2055:    SNESGetSolution - Returns the vector where the approximate solution is
2056:    stored.

2058:    Not Collective, but Vec is parallel if SNES is parallel

2060:    Input Parameter:
2061: .  snes - the SNES context

2063:    Output Parameter:
2064: .  x - the solution

2066:    Level: intermediate

2068: .keywords: SNES, nonlinear, get, solution

2070: .seealso:  SNESGetSolutionUpdate(), SNESGetFunction()
2071: @*/
2072: PetscErrorCode  SNESGetSolution(SNES snes,Vec *x)
2073: {
2077:   *x = snes->vec_sol;
2078:   return(0);
2079: }

2083: /*@
2084:    SNESGetSolutionUpdate - Returns the vector where the solution update is
2085:    stored. 

2087:    Not Collective, but Vec is parallel if SNES is parallel

2089:    Input Parameter:
2090: .  snes - the SNES context

2092:    Output Parameter:
2093: .  x - the solution update

2095:    Level: advanced

2097: .keywords: SNES, nonlinear, get, solution, update

2099: .seealso: SNESGetSolution(), SNESGetFunction()
2100: @*/
2101: PetscErrorCode  SNESGetSolutionUpdate(SNES snes,Vec *x)
2102: {
2106:   *x = snes->vec_sol_update;
2107:   return(0);
2108: }

2112: /*@C
2113:    SNESGetFunction - Returns the vector where the function is stored.

2115:    Not Collective, but Vec is parallel if SNES is parallel

2117:    Input Parameter:
2118: .  snes - the SNES context

2120:    Output Parameter:
2121: +  r - the function (or PETSC_NULL)
2122: .  func - the function (or PETSC_NULL)
2123: -  ctx - the function context (or PETSC_NULL)

2125:    Level: advanced

2127: .keywords: SNES, nonlinear, get, function

2129: .seealso: SNESSetFunction(), SNESGetSolution()
2130: @*/
2131: PetscErrorCode  SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**func)(SNES,Vec,Vec,void*),void **ctx)
2132: {
2135:   if (r)    *r    = snes->vec_func;
2136:   if (func) *func = snes->ops->computefunction;
2137:   if (ctx)  *ctx  = snes->funP;
2138:   return(0);
2139: }

2143: /*@C
2144:    SNESSetOptionsPrefix - Sets the prefix used for searching for all 
2145:    SNES options in the database.

2147:    Collective on SNES

2149:    Input Parameter:
2150: +  snes - the SNES context
2151: -  prefix - the prefix to prepend to all option names

2153:    Notes:
2154:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2155:    The first character of all runtime options is AUTOMATICALLY the hyphen.

2157:    Level: advanced

2159: .keywords: SNES, set, options, prefix, database

2161: .seealso: SNESSetFromOptions()
2162: @*/
2163: PetscErrorCode  SNESSetOptionsPrefix(SNES snes,const char prefix[])
2164: {

2169:   PetscObjectSetOptionsPrefix((PetscObject)snes,prefix);
2170:   KSPSetOptionsPrefix(snes->ksp,prefix);
2171:   return(0);
2172: }

2176: /*@C
2177:    SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 
2178:    SNES options in the database.

2180:    Collective on SNES

2182:    Input Parameters:
2183: +  snes - the SNES context
2184: -  prefix - the prefix to prepend to all option names

2186:    Notes:
2187:    A hyphen (-) must NOT be given at the beginning of the prefix name.
2188:    The first character of all runtime options is AUTOMATICALLY the hyphen.

2190:    Level: advanced

2192: .keywords: SNES, append, options, prefix, database

2194: .seealso: SNESGetOptionsPrefix()
2195: @*/
2196: PetscErrorCode  SNESAppendOptionsPrefix(SNES snes,const char prefix[])
2197: {
2199: 
2202:   PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix);
2203:   KSPAppendOptionsPrefix(snes->ksp,prefix);
2204:   return(0);
2205: }

2209: /*@C
2210:    SNESGetOptionsPrefix - Sets the prefix used for searching for all 
2211:    SNES options in the database.

2213:    Not Collective

2215:    Input Parameter:
2216: .  snes - the SNES context

2218:    Output Parameter:
2219: .  prefix - pointer to the prefix string used

2221:    Notes: On the fortran side, the user should pass in a string 'prifix' of
2222:    sufficient length to hold the prefix.

2224:    Level: advanced

2226: .keywords: SNES, get, options, prefix, database

2228: .seealso: SNESAppendOptionsPrefix()
2229: @*/
2230: PetscErrorCode  SNESGetOptionsPrefix(SNES snes,const char *prefix[])
2231: {

2236:   PetscObjectGetOptionsPrefix((PetscObject)snes,prefix);
2237:   return(0);
2238: }


2243: /*@C
2244:   SNESRegister - See SNESRegisterDynamic()

2246:   Level: advanced
2247: @*/
2248: PetscErrorCode  SNESRegister(const char sname[],const char path[],const char name[],PetscErrorCode (*function)(SNES))
2249: {
2250:   char           fullname[PETSC_MAX_PATH_LEN];

2254:   PetscFListConcat(path,name,fullname);
2255:   PetscFListAdd(&SNESList,sname,fullname,(void (*)(void))function);
2256:   return(0);
2257: }

2261: PetscErrorCode  SNESTestLocalMin(SNES snes)
2262: {
2264:   PetscInt       N,i,j;
2265:   Vec            u,uh,fh;
2266:   PetscScalar    value;
2267:   PetscReal      norm;

2270:   SNESGetSolution(snes,&u);
2271:   VecDuplicate(u,&uh);
2272:   VecDuplicate(u,&fh);

2274:   /* currently only works for sequential */
2275:   PetscPrintf(PETSC_COMM_WORLD,"Testing FormFunction() for local min\n");
2276:   VecGetSize(u,&N);
2277:   for (i=0; i<N; i++) {
2278:     VecCopy(u,uh);
2279:     PetscPrintf(PETSC_COMM_WORLD,"i = %D\n",i);
2280:     for (j=-10; j<11; j++) {
2281:       value = PetscSign(j)*exp(PetscAbs(j)-10.0);
2282:       VecSetValue(uh,i,value,ADD_VALUES);
2283:       SNESComputeFunction(snes,uh,fh);
2284:       VecNorm(fh,NORM_2,&norm);
2285:       PetscPrintf(PETSC_COMM_WORLD,"       j norm %D %18.16e\n",j,norm);
2286:       value = -value;
2287:       VecSetValue(uh,i,value,ADD_VALUES);
2288:     }
2289:   }
2290:   VecDestroy(uh);
2291:   VecDestroy(fh);
2292:   return(0);
2293: }

2297: /*@
2298:    SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for
2299:    computing relative tolerance for linear solvers within an inexact
2300:    Newton method.

2302:    Collective on SNES

2304:    Input Parameters:
2305: +  snes - SNES context
2306: -  flag - PETSC_TRUE or PETSC_FALSE

2308:    Notes:
2309:    Currently, the default is to use a constant relative tolerance for 
2310:    the inner linear solvers.  Alternatively, one can use the 
2311:    Eisenstat-Walker method, where the relative convergence tolerance 
2312:    is reset at each Newton iteration according progress of the nonlinear 
2313:    solver. 

2315:    Level: advanced

2317:    Reference:
2318:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2319:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

2321: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

2323: .seealso: SNESKSPGetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2324: @*/
2325: PetscErrorCode  SNESKSPSetUseEW(SNES snes,PetscTruth flag)
2326: {
2329:   snes->ksp_ewconv = flag;
2330:   return(0);
2331: }

2335: /*@
2336:    SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method
2337:    for computing relative tolerance for linear solvers within an
2338:    inexact Newton method.

2340:    Not Collective

2342:    Input Parameter:
2343: .  snes - SNES context

2345:    Output Parameter:
2346: .  flag - PETSC_TRUE or PETSC_FALSE

2348:    Notes:
2349:    Currently, the default is to use a constant relative tolerance for 
2350:    the inner linear solvers.  Alternatively, one can use the 
2351:    Eisenstat-Walker method, where the relative convergence tolerance 
2352:    is reset at each Newton iteration according progress of the nonlinear 
2353:    solver. 

2355:    Level: advanced

2357:    Reference:
2358:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2359:    inexact Newton method", SISC 17 (1), pp.16-32, 1996.

2361: .keywords: SNES, KSP, Eisenstat, Walker, convergence, test, inexact, Newton

2363: .seealso: SNESKSPSetUseEW(), SNESKSPGetParametersEW(), SNESKSPSetParametersEW()
2364: @*/
2365: PetscErrorCode  SNESKSPGetUseEW(SNES snes, PetscTruth *flag)
2366: {
2370:   *flag = snes->ksp_ewconv;
2371:   return(0);
2372: }

2376: /*@
2377:    SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker
2378:    convergence criteria for the linear solvers within an inexact
2379:    Newton method.

2381:    Collective on SNES
2382:  
2383:    Input Parameters:
2384: +    snes - SNES context
2385: .    version - version 1, 2 (default is 2) or 3
2386: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2387: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2388: .    gamma - multiplicative factor for version 2 rtol computation
2389:              (0 <= gamma2 <= 1)
2390: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2391: .    alpha2 - power for safeguard
2392: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2394:    Note:
2395:    Version 3 was contributed by Luis Chacon, June 2006.

2397:    Use PETSC_DEFAULT to retain the default for any of the parameters.

2399:    Level: advanced

2401:    Reference:
2402:    S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 
2403:    inexact Newton method", Utah State University Math. Stat. Dept. Res. 
2404:    Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 

2406: .keywords: SNES, KSP, Eisenstat, Walker, set, parameters

2408: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPGetParametersEW()
2409: @*/
2410: PetscErrorCode  SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,
2411:                                                             PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold)
2412: {
2413:   SNESKSPEW *kctx;
2416:   kctx = (SNESKSPEW*)snes->kspconvctx;
2417:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");

2419:   if (version != PETSC_DEFAULT)   kctx->version   = version;
2420:   if (rtol_0 != PETSC_DEFAULT)    kctx->rtol_0    = rtol_0;
2421:   if (rtol_max != PETSC_DEFAULT)  kctx->rtol_max  = rtol_max;
2422:   if (gamma != PETSC_DEFAULT)     kctx->gamma     = gamma;
2423:   if (alpha != PETSC_DEFAULT)     kctx->alpha     = alpha;
2424:   if (alpha2 != PETSC_DEFAULT)    kctx->alpha2    = alpha2;
2425:   if (threshold != PETSC_DEFAULT) kctx->threshold = threshold;
2426: 
2427:   if (kctx->version < 1 || kctx->version > 3) {
2428:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 and 3 are supported: %D",kctx->version);
2429:   }
2430:   if (kctx->rtol_0 < 0.0 || kctx->rtol_0 >= 1.0) {
2431:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %G",kctx->rtol_0);
2432:   }
2433:   if (kctx->rtol_max < 0.0 || kctx->rtol_max >= 1.0) {
2434:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%G) < 1.0\n",kctx->rtol_max);
2435:   }
2436:   if (kctx->gamma < 0.0 || kctx->gamma > 1.0) {
2437:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%G) <= 1.0\n",kctx->gamma);
2438:   }
2439:   if (kctx->alpha <= 1.0 || kctx->alpha > 2.0) {
2440:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%G) <= 2.0\n",kctx->alpha);
2441:   }
2442:   if (kctx->threshold <= 0.0 || kctx->threshold >= 1.0) {
2443:     SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%G) < 1.0\n",kctx->threshold);
2444:   }
2445:   return(0);
2446: }

2450: /*@
2451:    SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker
2452:    convergence criteria for the linear solvers within an inexact
2453:    Newton method.

2455:    Not Collective
2456:  
2457:    Input Parameters:
2458:      snes - SNES context

2460:    Output Parameters:
2461: +    version - version 1, 2 (default is 2) or 3
2462: .    rtol_0 - initial relative tolerance (0 <= rtol_0 < 1)
2463: .    rtol_max - maximum relative tolerance (0 <= rtol_max < 1)
2464: .    gamma - multiplicative factor for version 2 rtol computation
2465:              (0 <= gamma2 <= 1)
2466: .    alpha - power for version 2 rtol computation (1 < alpha <= 2)
2467: .    alpha2 - power for safeguard
2468: -    threshold - threshold for imposing safeguard (0 < threshold < 1)

2470:    Level: advanced

2472: .keywords: SNES, KSP, Eisenstat, Walker, get, parameters

2474: .seealso: SNESKSPSetUseEW(), SNESKSPGetUseEW(), SNESKSPSetParametersEW()
2475: @*/
2476: PetscErrorCode  SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,
2477:                                                             PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold)
2478: {
2479:   SNESKSPEW *kctx;
2482:   kctx = (SNESKSPEW*)snes->kspconvctx;
2483:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing");
2484:   if(version)   *version   = kctx->version;
2485:   if(rtol_0)    *rtol_0    = kctx->rtol_0;
2486:   if(rtol_max)  *rtol_max  = kctx->rtol_max;
2487:   if(gamma)     *gamma     = kctx->gamma;
2488:   if(alpha)     *alpha     = kctx->alpha;
2489:   if(alpha2)    *alpha2    = kctx->alpha2;
2490:   if(threshold) *threshold = kctx->threshold;
2491:   return(0);
2492: }

2496: static PetscErrorCode SNESKSPEW_PreSolve(SNES snes, KSP ksp, Vec b, Vec x)
2497: {
2499:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2500:   PetscReal      rtol=PETSC_DEFAULT,stol;

2503:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2504:   if (!snes->iter) { /* first time in, so use the original user rtol */
2505:     rtol = kctx->rtol_0;
2506:   } else {
2507:     if (kctx->version == 1) {
2508:       rtol = (snes->norm - kctx->lresid_last)/kctx->norm_last;
2509:       if (rtol < 0.0) rtol = -rtol;
2510:       stol = pow(kctx->rtol_last,kctx->alpha2);
2511:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2512:     } else if (kctx->version == 2) {
2513:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2514:       stol = kctx->gamma * pow(kctx->rtol_last,kctx->alpha);
2515:       if (stol > kctx->threshold) rtol = PetscMax(rtol,stol);
2516:     } else if (kctx->version == 3) {/* contributed by Luis Chacon, June 2006. */
2517:       rtol = kctx->gamma * pow(snes->norm/kctx->norm_last,kctx->alpha);
2518:       /* safeguard: avoid sharp decrease of rtol */
2519:       stol = kctx->gamma*pow(kctx->rtol_last,kctx->alpha);
2520:       stol = PetscMax(rtol,stol);
2521:       rtol = PetscMin(kctx->rtol_0,stol);
2522:       /* safeguard: avoid oversolving */
2523:       stol = kctx->gamma*(snes->ttol)/snes->norm;
2524:       stol = PetscMax(rtol,stol);
2525:       rtol = PetscMin(kctx->rtol_0,stol);
2526:     } else SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1, 2 or 3 are supported: %D",kctx->version);
2527:   }
2528:   /* safeguard: avoid rtol greater than one */
2529:   rtol = PetscMin(rtol,kctx->rtol_max);
2530:   KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);
2531:   PetscInfo3(snes,"iter %D, Eisenstat-Walker (version %D) KSP rtol=%G\n",snes->iter,kctx->version,rtol);
2532:   return(0);
2533: }

2537: static PetscErrorCode SNESKSPEW_PostSolve(SNES snes, KSP ksp, Vec b, Vec x)
2538: {
2540:   SNESKSPEW      *kctx = (SNESKSPEW*)snes->kspconvctx;
2541:   PCSide         pcside;
2542:   Vec            lres;

2545:   if (!kctx) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context exists");
2546:   KSPGetTolerances(ksp,&kctx->rtol_last,0,0,0);
2547:   SNESGetFunctionNorm(snes,&kctx->norm_last);
2548:   if (kctx->version == 1) {
2549:     KSPGetPreconditionerSide(ksp,&pcside);
2550:     if (pcside == PC_RIGHT) { /* XXX Should we also test KSP_UNPRECONDITIONED_NORM ? */
2551:       /* KSP residual is true linear residual */
2552:       KSPGetResidualNorm(ksp,&kctx->lresid_last);
2553:     } else {
2554:       /* KSP residual is preconditioned residual */
2555:       /* compute true linear residual norm */
2556:       VecDuplicate(b,&lres);
2557:       MatMult(snes->jacobian,x,lres);
2558:       VecAYPX(lres,-1.0,b);
2559:       VecNorm(lres,NORM_2,&kctx->lresid_last);
2560:       VecDestroy(lres);
2561:     }
2562:   }
2563:   return(0);
2564: }

2568: PetscErrorCode SNES_KSPSolve(SNES snes, KSP ksp, Vec b, Vec x)
2569: {

2573:   if (snes->ksp_ewconv) { SNESKSPEW_PreSolve(snes,ksp,b,x);  }
2574:   KSPSolve(ksp,b,x);
2575:   if (snes->ksp_ewconv) { SNESKSPEW_PostSolve(snes,ksp,b,x); }
2576:   return(0);
2577: }