Actual source code: itcl.c
petsc-3.3-p7 2013-05-11
2: /*
3: Code for setting KSP options from the options database.
4: */
6: #include <petsc-private/kspimpl.h> /*I "petscksp.h" I*/
8: extern PetscBool KSPRegisterAllCalled;
12: /*@C
13: KSPSetOptionsPrefix - Sets the prefix used for searching for all
14: KSP options in the database.
16: Logically Collective on KSP
18: Input Parameters:
19: + ksp - the Krylov context
20: - prefix - the prefix string to prepend to all KSP option requests
22: Notes:
23: A hyphen (-) must NOT be given at the beginning of the prefix name.
24: The first character of all runtime options is AUTOMATICALLY the
25: hyphen.
27: For example, to distinguish between the runtime options for two
28: different KSP contexts, one could call
29: .vb
30: KSPSetOptionsPrefix(ksp1,"sys1_")
31: KSPSetOptionsPrefix(ksp2,"sys2_")
32: .ve
34: This would enable use of different options for each system, such as
35: .vb
36: -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
37: -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
38: .ve
40: Level: advanced
42: .keywords: KSP, set, options, prefix, database
44: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
45: @*/
46: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
47: {
51: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
52: PCSetOptionsPrefix(ksp->pc,prefix);
53: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
54: return(0);
55: }
56:
59: /*@C
60: KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
61: KSP options in the database.
63: Logically Collective on KSP
65: Input Parameters:
66: + ksp - the Krylov context
67: - prefix - the prefix string to prepend to all KSP option requests
69: Notes:
70: A hyphen (-) must NOT be given at the beginning of the prefix name.
71: The first character of all runtime options is AUTOMATICALLY the hyphen.
73: Level: advanced
75: .keywords: KSP, append, options, prefix, database
77: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
78: @*/
79: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
80: {
84: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
85: PCAppendOptionsPrefix(ksp->pc,prefix);
86: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
87: return(0);
88: }
92: /*@C
93: KSPSetUseFischerGuess - Use the Paul Fischer algorithm, see KSPFischerGuessCreate()
95: Logically Collective on KSP
97: Input Parameters:
98: + ksp - the Krylov context
99: . model - use model 1, model 2 or 0 to turn it off
100: - size - size of subspace used to generate initial guess
102: Options Database:
103: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
105: Level: advanced
107: .keywords: KSP, set, options, prefix, database
109: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerInitialGuess()
110: @*/
111: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
112: {
118: KSPFischerGuessDestroy(&ksp->guess);
119: if (model == 1 || model == 2) {
120: KSPFischerGuessCreate(ksp,model,size,&ksp->guess);
121: KSPFischerGuessSetFromOptions(ksp->guess);
122: } 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)");
123: return(0);
124: }
128: /*@C
129: KSPSetFischerGuess - Use the Paul Fischer algorithm created by KSPFischerGuessCreate()
131: Logically Collective on KSP
133: Input Parameters:
134: + ksp - the Krylov context
135: - guess - the object created with KSPFischerGuessCreate()
137: Level: advanced
139: Notes: this allows a single KSP to be used with several different initial guess generators (likely for different linear
140: solvers, see KSPSetPC()).
142: This increases the reference count of the guess object, you must destroy the object with KSPFischerGuessDestroy()
143: before the end of the program.
145: .keywords: KSP, set, options, prefix, database
147: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerGuess()
148: @*/
149: PetscErrorCode KSPSetFischerGuess(KSP ksp,KSPFischerGuess guess)
150: {
154: KSPFischerGuessDestroy(&ksp->guess);
155: ksp->guess = guess;
156: if (guess) guess->refcnt++;
157: return(0);
158: }
162: /*@C
163: KSPGetFischerGuess - Gets the initial guess generator set with either KSPSetFischerGuess() or KSPCreateFischerGuess()/KSPSetFischerGuess()
165: Not Collective
167: Input Parameters:
168: . ksp - the Krylov context
170: Output Parameters:
171: . guess - the object
173: Level: developer
175: .keywords: KSP, set, options, prefix, database
177: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess()
178: @*/
179: PetscErrorCode KSPGetFischerGuess(KSP ksp,KSPFischerGuess *guess)
180: {
182: *guess = ksp->guess;
183: return(0);
184: }
188: /*@C
189: KSPGetOptionsPrefix - Gets the prefix used for searching for all
190: KSP options in the database.
192: Not Collective
194: Input Parameters:
195: . ksp - the Krylov context
197: Output Parameters:
198: . prefix - pointer to the prefix string used is returned
200: Notes: On the fortran side, the user should pass in a string 'prifix' of
201: sufficient length to hold the prefix.
203: Level: advanced
205: .keywords: KSP, set, options, prefix, database
207: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
208: @*/
209: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
210: {
214: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
215: return(0);
216: }
220: /*@
221: KSPSetFromOptions - Sets KSP options from the options database.
222: This routine must be called before KSPSetUp() if the user is to be
223: allowed to set the Krylov type.
225: Collective on KSP
227: Input Parameters:
228: . ksp - the Krylov space context
230: Options Database Keys:
231: + -ksp_max_it - maximum number of linear iterations
232: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
233: if residual norm decreases by this factor than convergence is declared
234: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
235: norm is less than this then convergence is declared
236: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
237: . -ksp_converged_use_initial_residual_norm - see KSPDefaultConvergedSetUIRNorm()
238: . -ksp_converged_use_min_initial_residual_norm - see KSPDefaultConvergedSetUMIRNorm()
239: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
240: $ convergence test (say you always want to run with 5 iterations) to
241: $ save on communication overhead
242: $ preconditioned - default for left preconditioning
243: $ unpreconditioned - see KSPSetNormType()
244: $ natural - see KSPSetNormType()
245: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
246: $ works only for PCBCGS, PCIBCGS and and PCCG
247: -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
248: $ the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
249: $ This will require 1 more iteration of the solver than usual.
250: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
251: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
252: . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
253: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
254: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
255: . -ksp_monitor <optional filename> - print residual norm at each iteration
256: . -ksp_monitor_draw - plot residual norm at each iteration
257: . -ksp_monitor_solution - plot solution at each iteration
258: - -ksp_monitor_singular_value - monitor extremem singular values at each iteration
260: Notes:
261: To see all options, run your program with the -help option
262: or consult <A href="../../docs/manual.pdf#nameddest=Chapter 4 KSP: Linear Equations Solvers">KSP chapter of the users manual</A>.
264: Level: beginner
266: .keywords: KSP, set, from, options, database
268: .seealso: KSPSetUseFischerInitialGuess()
270: @*/
271: PetscErrorCode KSPSetFromOptions(KSP ksp)
272: {
273: PetscErrorCode ierr;
274: PetscInt indx;
275: const char *convtests[] = {"default","skip"};
276: char type[256], monfilename[PETSC_MAX_PATH_LEN];
277: PetscViewer monviewer;
278: PetscBool flg,flag;
279: PetscInt model[2]={0,0},nmax;
280: KSPNormType normtype;
281: PCSide pcside;
282: void *ctx;
286: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
287: PCSetFromOptions(ksp->pc);
289: if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
290: PetscObjectOptionsBegin((PetscObject)ksp);
291: PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name?((PetscObject)ksp)->type_name:KSPGMRES),type,256,&flg);
292: if (flg) {
293: KSPSetType(ksp,type);
294: }
295: /*
296: Set the type if it was never set.
297: */
298: if (!((PetscObject)ksp)->type_name) {
299: KSPSetType(ksp,KSPGMRES);
300: }
302: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
303: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
304: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,PETSC_NULL);
305: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);
307: flag = PETSC_FALSE;
308: PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPDefaultConvergedSetUIRNorm",flag,&flag,PETSC_NULL);
309: if (flag) {KSPDefaultConvergedSetUIRNorm(ksp);}
310: flag = PETSC_FALSE;
311: 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);
312: if (flag) {KSPDefaultConvergedSetUMIRNorm(ksp);}
313: KSPGetInitialGuessNonzero(ksp,&flag);
314: PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);
315: if (flg) {
316: KSPSetInitialGuessNonzero(ksp,flag);
317: }
319: PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,PETSC_NULL);
320: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,PETSC_NULL);
321: nmax = 2;
322: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
323: if (flag) {
324: if (nmax != 2) SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
325: KSPSetUseFischerGuess(ksp,model[0],model[1]);
326: }
328: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
329: if (flg) {
330: switch (indx) {
331: case 0:
332: KSPDefaultConvergedCreate(&ctx);
333: KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);
334: break;
335: case 1: KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL,PETSC_NULL); break;
336: }
337: }
339: KSPSetUpNorms_Private(ksp,&normtype,&pcside);
340: PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
341: if (flg) { KSPSetNormType(ksp,normtype); }
343: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,PETSC_NULL);
345: flag = ksp->lagnorm;
346: PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);
347: if (flg) {
348: KSPSetLagNorm(ksp,flag);
349: }
351: KSPGetDiagonalScale(ksp,&flag);
352: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
353: if (flg) {
354: KSPSetDiagonalScale(ksp,flag);
355: }
356: KSPGetDiagonalScaleFix(ksp,&flag);
357: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
358: if (flg) {
359: KSPSetDiagonalScaleFix(ksp,flag);
360: }
362: flg = PETSC_FALSE;
363: PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,PETSC_NULL);
364: if (flg) {
365: MatNullSpace nsp;
367: MatNullSpaceCreate(((PetscObject)ksp)->comm,PETSC_TRUE,0,0,&nsp);
368: KSPSetNullSpace(ksp,nsp);
369: MatNullSpaceDestroy(&nsp);
370: }
372: /* option is actually checked in KSPSetUp(), just here so goes into help message */
373: if (ksp->nullsp) {
374: PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
375: }
377: /*
378: Prints reason for convergence or divergence of each linear solve
379: */
380: flg = PETSC_FALSE;
381: PetscOptionsBool("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,PETSC_NULL);
382: if (flg) {
383: ksp->printreason = PETSC_TRUE;
384: }
386: flg = PETSC_FALSE;
387: PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,PETSC_NULL);
388: /* -----------------------------------------------------------------------*/
389: /*
390: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
391: */
392: if (flg) {
393: KSPMonitorCancel(ksp);
394: }
395: /*
396: Prints preconditioned residual norm at each iteration
397: */
398: PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
399: if (flg) {
400: PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
401: KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
402: }
403: /*
404: Prints preconditioned residual norm at each iteration
405: */
406: PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
407: if (flg) {
408: PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
409: KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
410: }
411: /*
412: Plots the vector solution
413: */
414: flg = PETSC_FALSE;
415: PetscOptionsBool("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,PETSC_NULL);
416: if (flg) {
417: KSPMonitorSet(ksp,KSPMonitorSolution,PETSC_NULL,PETSC_NULL);
418: }
419: /*
420: Prints preconditioned and true residual norm at each iteration
421: */
422: PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
423: if (flg) {
424: PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
425: KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
426: }
427: /*
428: Prints extreme eigenvalue estimates at each iteration
429: */
430: PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
431: if (flg) {
432: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
433: PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
434: KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
435: }
436: /*
437: Prints preconditioned residual norm with fewer digits
438: */
439: PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
440: if (flg) {
441: PetscViewerASCIIOpen(((PetscObject)ksp)->comm,monfilename,&monviewer);
442: KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
443: }
444: /*
445: Calls Python function
446: */
447: PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
448: if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
449: /*
450: Graphically plots preconditioned residual norm
451: */
452: flg = PETSC_FALSE;
453: PetscOptionsBool("-ksp_monitor_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
454: if (flg) {
455: KSPMonitorSet(ksp,KSPMonitorLG,PETSC_NULL,PETSC_NULL);
456: }
457: /*
458: Graphically plots preconditioned and true residual norm
459: */
460: flg = PETSC_FALSE;
461: PetscOptionsBool("-ksp_monitor_draw_true_residual","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
462: if (flg){
463: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,PETSC_NULL,PETSC_NULL);
464: }
465: /*
466: Graphically plots preconditioned residual norm and range of residual element values
467: */
468: flg = PETSC_FALSE;
469: PetscOptionsBool("-ksp_monitor_range_draw","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
470: if (flg) {
471: KSPMonitorSet(ksp,KSPMonitorLGRange,PETSC_NULL,PETSC_NULL);
472: }
474: /*
475: Publishes convergence information using AMS
476: */
477: flg = PETSC_FALSE;
478: PetscOptionsBool("-ksp_monitor_ams","Publish KSP progress using AMS","KSPMonitorSet",flg,&flg,PETSC_NULL);
479: if (flg) {
480: char amscommname[256];
481: void *ctx;
482: PetscSNPrintf(amscommname,sizeof amscommname,"%sksp_monitor_ams",((PetscObject)ksp)->prefix?((PetscObject)ksp)->prefix:"");
483: KSPMonitorAMSCreate(ksp,amscommname,&ctx);
484: KSPMonitorSet(ksp,KSPMonitorAMS,ctx,KSPMonitorAMSDestroy);
485: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
486: }
488: /* -----------------------------------------------------------------------*/
489: KSPSetUpNorms_Private(ksp,&normtype,&pcside);
490: PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
491: if (flg) {KSPSetPCSide(ksp,pcside);}
493: flg = PETSC_FALSE;
494: PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
495: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
496: flg = PETSC_FALSE;
497: PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
498: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
499: flg = PETSC_FALSE;
500: PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
501: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
504: if (ksp->ops->setfromoptions) {
505: (*ksp->ops->setfromoptions)(ksp);
506: }
507: /* actually check in setup this is just here so goes into help message */
508: PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
510: /* process any options handlers added with PetscObjectAddOptionsHandler() */
511: PetscObjectProcessOptionsHandlers((PetscObject)ksp);
512: PetscOptionsEnd();
513: return(0);
514: }