Actual source code: itcl.c

  2: /*
  3:     Code for setting KSP options from the options database.
  4: */

  6: #include <private/kspimpl.h>  /*I "petscksp.h" I*/



 13: /*@C
 14:    KSPSetOptionsPrefix - Sets the prefix used for searching for all 
 15:    KSP options in the database.

 17:    Logically Collective on KSP

 19:    Input Parameters:
 20: +  ksp - the Krylov context
 21: -  prefix - the prefix string to prepend to all KSP option requests

 23:    Notes:
 24:    A hyphen (-) must NOT be given at the beginning of the prefix name.
 25:    The first character of all runtime options is AUTOMATICALLY the
 26:    hyphen.

 28:    For example, to distinguish between the runtime options for two
 29:    different KSP contexts, one could call
 30: .vb
 31:       KSPSetOptionsPrefix(ksp1,"sys1_")
 32:       KSPSetOptionsPrefix(ksp2,"sys2_")
 33: .ve

 35:    This would enable use of different options for each system, such as
 36: .vb
 37:       -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
 38:       -sys2_ksp_type bcgs  -sys2_ksp_rtol 1.e-4
 39: .ve

 41:    Level: advanced

 43: .keywords: KSP, set, options, prefix, database

 45: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
 46: @*/
 47: PetscErrorCode  KSPSetOptionsPrefix(KSP ksp,const char prefix[])
 48: {
 52:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
 53:   PCSetOptionsPrefix(ksp->pc,prefix);
 54:   PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
 55:   return(0);
 56: }
 57: 
 60: /*@C
 61:    KSPAppendOptionsPrefix - Appends to the prefix used for searching for all 
 62:    KSP options in the database.

 64:    Logically Collective on KSP

 66:    Input Parameters:
 67: +  ksp - the Krylov context
 68: -  prefix - the prefix string to prepend to all KSP option requests

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

 74:    Level: advanced

 76: .keywords: KSP, append, options, prefix, database

 78: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
 79: @*/
 80: PetscErrorCode  KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
 81: {
 85:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
 86:   PCAppendOptionsPrefix(ksp->pc,prefix);
 87:   PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
 88:   return(0);
 89: }

 93: /*@C
 94:    KSPSetUseFischerGuess - Use the Paul Fischer algorithm, see KSPFischerGuessCreate()

 96:    Logically Collective on KSP

 98:    Input Parameters:
 99: +  ksp - the Krylov context
100: .  model - use model 1, model 2 or 0 to turn it off
101: -  size - size of subspace used to generate initial guess

103:     Options Database:
104: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves

106:    Level: advanced

108: .keywords: KSP, set, options, prefix, database

110: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerInitialGuess()
111: @*/
112: PetscErrorCode  KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
113: {
119:   KSPFischerGuessDestroy(&ksp->guess);
120:   if (model == 1 || model == 2) {
121:     KSPFischerGuessCreate(ksp,model,size,&ksp->guess);
122:     KSPFischerGuessSetFromOptions(ksp->guess);
123:   } else if (model != 0) SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Model must be 1 or 2 (or 0 to turn off guess generation)");
124:   return(0);
125: }

129: /*@C
130:    KSPSetFischerGuess - Use the Paul Fischer algorithm created by KSPFischerGuessCreate()

132:    Logically Collective on KSP

134:    Input Parameters:
135: +  ksp - the Krylov context
136: -  guess - the object created with KSPFischerGuessCreate()

138:    Level: advanced

140:    Notes: this allows a single KSP to be used with several different initial guess generators (likely for different linear
141:           solvers, see KSPSetPC()).

143:           This increases the reference count of the guess object, you must destroy the object with KSPFischerGuessDestroy()
144:           before the end of the program.

146: .keywords: KSP, set, options, prefix, database

148: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerGuess()
149: @*/
150: PetscErrorCode  KSPSetFischerGuess(KSP ksp,KSPFischerGuess guess)
151: {
155:   KSPFischerGuessDestroy(&ksp->guess);
156:   ksp->guess = guess;
157:   if (guess) guess->refcnt++;
158:   return(0);
159: }

163: /*@C
164:    KSPGetFischerGuess - Gets the initial guess generator set with either KSPSetFischerGuess() or KSPCreateFischerGuess()/KSPSetFischerGuess()

166:    Not Collective

168:    Input Parameters:
169: .  ksp - the Krylov context

171:    Output Parameters:
172: .   guess - the object

174:    Level: developer

176: .keywords: KSP, set, options, prefix, database

178: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess()
179: @*/
180: PetscErrorCode  KSPGetFischerGuess(KSP ksp,KSPFischerGuess *guess)
181: {
183:   *guess = ksp->guess;
184:   return(0);
185: }

189: /*@C
190:    KSPGetOptionsPrefix - Gets the prefix used for searching for all 
191:    KSP options in the database.

193:    Not Collective

195:    Input Parameters:
196: .  ksp - the Krylov context

198:    Output Parameters:
199: .  prefix - pointer to the prefix string used is returned

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

204:    Level: advanced

206: .keywords: KSP, set, options, prefix, database

208: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
209: @*/
210: PetscErrorCode  KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
211: {
215:   PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
216:   return(0);
217: }

221: /*@
222:    KSPSetFromOptions - Sets KSP options from the options database.
223:    This routine must be called before KSPSetUp() if the user is to be 
224:    allowed to set the Krylov type. 

226:    Collective on KSP

228:    Input Parameters:
229: .  ksp - the Krylov space context

231:    Options Database Keys:
232: +   -ksp_max_it - maximum number of linear iterations
233: .   -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
234:                 if residual norm decreases by this factor than convergence is declared
235: .   -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual 
236:                 norm is less than this then convergence is declared
237: .   -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
238: .   -ksp_converged_use_initial_residual_norm - see KSPDefaultConvergedSetUIRNorm()
239: .   -ksp_converged_use_min_initial_residual_norm - see KSPDefaultConvergedSetUMIRNorm()
240: .   -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using 
241: $                       convergence test (say you always want to run with 5 iterations) to 
242: $                       save on communication overhead
243: $                    preconditioned - default for left preconditioning 
244: $                    unpreconditioned - see KSPSetNormType()
245: $                    natural - see KSPSetNormType()
246: .   -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
247: $       works only for PCBCGS, PCIBCGS and and PCCG
248:     -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
249: $       the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
250: $       This will require 1 more iteration of the solver than usual.
251: .   -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
252: .   -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
253: .   -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
254: .   -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
255: .   -ksp_monitor_cancel - cancel all previous convergene monitor routines set
256: .   -ksp_monitor <optional filename> - print residual norm at each iteration
257: .   -ksp_monitor_draw - plot residual norm at each iteration
258: .   -ksp_monitor_solution - plot solution at each iteration
259: -   -ksp_monitor_singular_value - monitor extremem singular values at each iteration

261:    Notes:  
262:    To see all options, run your program with the -help option
263:    or consult <A href="../../docs/manual.pdf#nameddest=Chapter 4 KSP: Linear Equations Solvers">KSP chapter of the users manual</A>.

265:    Level: beginner

267: .keywords: KSP, set, from, options, database

269: .seealso: KSPSetUseFischerInitialGuess()

271: @*/
272: PetscErrorCode  KSPSetFromOptions(KSP ksp)
273: {
274:   PetscErrorCode          ierr;
275:   PetscInt                indx;
276:   const char             *convtests[] = {"default","skip"};
277:   char                    type[256], monfilename[PETSC_MAX_PATH_LEN];
278:   PetscViewer             monviewer;
279:   PetscBool               flg,flag;
280:   PetscInt                model[2],nmax;
281:   void                    *ctx;

285:   if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
286:   PCSetFromOptions(ksp->pc);

288:   if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
289:   PetscObjectOptionsBegin((PetscObject)ksp);
290:     PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name?((PetscObject)ksp)->type_name:KSPGMRES),type,256,&flg);
291:     if (flg) {
292:       KSPSetType(ksp,type);
293:     }
294:     /*
295:       Set the type if it was never set.
296:     */
297:     if (!((PetscObject)ksp)->type_name) {
298:       KSPSetType(ksp,KSPGMRES);
299:     }

301:     PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
302:     PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
303:     PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,PETSC_NULL);
304:     PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);

306:     flag = PETSC_FALSE;
307:     PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPDefaultConvergedSetUIRNorm",flag,&flag,PETSC_NULL);
308:     if (flag) {KSPDefaultConvergedSetUIRNorm(ksp);}
309:     flag = PETSC_FALSE;
310:     PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPDefaultConvergedSetUMIRNorm",flag,&flag,PETSC_NULL);
311:     if (flag) {KSPDefaultConvergedSetUMIRNorm(ksp);}
312:     KSPGetInitialGuessNonzero(ksp,&flag);
313:     PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);
314:     if (flg) {
315:       KSPSetInitialGuessNonzero(ksp,flag);
316:     }

318:     PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,PETSC_NULL);
319:     PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,PETSC_NULL);
320:     nmax = 2;
321:     PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
322:     if (flag) {
323:       if (nmax != 2) SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
324:       KSPSetUseFischerGuess(ksp,model[0],model[1]);
325:     }

327:     PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
328:     if (flg) {
329:       switch (indx) {
330:       case 0:
331:         KSPDefaultConvergedCreate(&ctx);
332:         KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);
333:         break;
334:       case 1: KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL,PETSC_NULL);    break;
335:       }
336:     }

338:     PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,4,"preconditioned",&indx,&flg);
339:     if (flg) { KSPSetNormType(ksp,(KSPNormType)indx); }

341:     PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,PETSC_NULL);

343:     flag  = ksp->lagnorm;
344:     PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);
345:     if (flg) {
346:       KSPSetLagNorm(ksp,flag);
347:     }

349:     KSPGetDiagonalScale(ksp,&flag);
350:     PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
351:     if (flg) {
352:       KSPSetDiagonalScale(ksp,flag);
353:     }
354:     KSPGetDiagonalScaleFix(ksp,&flag);
355:     PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
356:     if (flg) {
357:       KSPSetDiagonalScaleFix(ksp,flag);
358:     }

360:     flg  = PETSC_FALSE;
361:     PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,PETSC_NULL);
362:     if (flg) {
363:       MatNullSpace nsp;

365:       MatNullSpaceCreate(((PetscObject)ksp)->comm,PETSC_TRUE,0,0,&nsp);
366:       KSPSetNullSpace(ksp,nsp);
367:       MatNullSpaceDestroy(&nsp);
368:     }

370:     /* option is actually checked in KSPSetUp(), just here so goes into help message */
371:     if (ksp->nullsp) {
372:       PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
373:     }

375:     /*
376:       Prints reason for convergence or divergence of each linear solve
377:     */
378:     flg = PETSC_FALSE;
379:     PetscOptionsBool("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,PETSC_NULL);
380:     if (flg) {
381:       ksp->printreason = PETSC_TRUE;
382:     }

384:     flg  = PETSC_FALSE;
385:     PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,PETSC_NULL);
386:     /* -----------------------------------------------------------------------*/
387:     /*
388:       Cancels all monitors hardwired into code before call to KSPSetFromOptions()
389:     */
390:     if (flg) {
391:       KSPMonitorCancel(ksp);
392:     }
393:     /*
394:       Prints preconditioned residual norm at each iteration
395:     */
396:     PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
397:     if (flg) {
398:       PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
399:       KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
400:     }
401:     /*
402:       Prints preconditioned residual norm at each iteration
403:     */
404:     PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
405:     if (flg) {
406:       PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
407:       KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
408:     }
409:     /*
410:       Plots the vector solution 
411:     */
412:     flg  = PETSC_FALSE;
413:     PetscOptionsBool("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,PETSC_NULL);
414:     if (flg) {
415:       KSPMonitorSet(ksp,KSPMonitorSolution,PETSC_NULL,PETSC_NULL);
416:     }
417:     /*
418:       Prints preconditioned and true residual norm at each iteration
419:     */
420:     PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
421:     if (flg) {
422:       PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
423:       KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
424:     }
425:     /*
426:       Prints extreme eigenvalue estimates at each iteration
427:     */
428:     PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
429:     if (flg) {
430:       KSPSetComputeSingularValues(ksp,PETSC_TRUE);
431:       PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
432:       KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
433:     }
434:     /*
435:       Prints preconditioned residual norm with fewer digits
436:     */
437:     PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
438:     if (flg) {
439:       PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
440:       KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
441:     }
442:     /*
443:      Calls Python function
444:     */
445:     PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
446:     if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
447:     /*
448:       Graphically plots preconditioned residual norm
449:     */
450:     flg  = PETSC_FALSE;
451:     PetscOptionsBool("-ksp_monitor_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
452:     if (flg) {
453:       KSPMonitorSet(ksp,KSPMonitorLG,PETSC_NULL,PETSC_NULL);
454:     }
455:     /*
456:       Graphically plots preconditioned and true residual norm
457:     */
458:     flg  = PETSC_FALSE;
459:     PetscOptionsBool("-ksp_monitor_draw_true_residual","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
460:     if (flg){
461:       KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,PETSC_NULL,PETSC_NULL);
462:     }
463:     /*
464:       Graphically plots preconditioned residual norm and range of residual element values
465:     */
466:     flg  = PETSC_FALSE;
467:     PetscOptionsBool("-ksp_monitor_range_draw","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
468:     if (flg) {
469:       KSPMonitorSet(ksp,KSPMonitorLGRange,PETSC_NULL,PETSC_NULL);
470:     }

472:     /* -----------------------------------------------------------------------*/
473:    PetscOptionsEList("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,3,PCSides[ksp->pc_side],&indx,&flg);
474:    if (flg) {KSPSetPCSide(ksp,(PCSide)indx);}

476:     flg  = PETSC_FALSE;
477:     PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
478:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
479:     flg  = PETSC_FALSE;
480:     PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
481:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
482:     flg  = PETSC_FALSE;
483:     PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
484:     if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }


487:     if (ksp->ops->setfromoptions) {
488:       (*ksp->ops->setfromoptions)(ksp);
489:     }
490:     /* actually check in setup this is just here so goes into help message */
491:     PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);

493:     /* process any options handlers added with PetscObjectAddOptionsHandler() */
494:     PetscObjectProcessOptionsHandlers((PetscObject)ksp);
495:   PetscOptionsEnd();
496:   return(0);
497: }