Actual source code: itcl.c
1: #define PETSCKSP_DLL
3: /*
4: Code for setting KSP options from the options database.
5: */
7: #include private/kspimpl.h
9: /*
10: We retain a list of functions that also take KSP command
11: line options. These are called at the end KSPSetFromOptions()
12: */
13: #define MAXSETFROMOPTIONS 5
14: PetscInt numberofsetfromoptions = 0;
15: PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(KSP) = {0};
21: /*@C
22: KSPAddOptionsChecker - Adds an additional function to check for KSP options.
24: Not Collective
26: Input Parameter:
27: . kspcheck - function that checks for options
29: Level: developer
31: .keywords: KSP, add, options, checker
33: .seealso: KSPSetFromOptions()
34: @*/
35: PetscErrorCode KSPAddOptionsChecker(PetscErrorCode (*kspcheck)(KSP))
36: {
38: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
39: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many options checkers, only 5 allowed");
40: }
42: othersetfromoptions[numberofsetfromoptions++] = kspcheck;
43: return(0);
44: }
48: /*@C
49: KSPSetOptionsPrefix - Sets the prefix used for searching for all
50: KSP options in the database.
52: Collective on KSP
54: Input Parameters:
55: + ksp - the Krylov context
56: - prefix - the prefix string to prepend to all KSP option requests
58: Notes:
59: A hyphen (-) must NOT be given at the beginning of the prefix name.
60: The first character of all runtime options is AUTOMATICALLY the
61: hyphen.
63: For example, to distinguish between the runtime options for two
64: different KSP contexts, one could call
65: .vb
66: KSPSetOptionsPrefix(ksp1,"sys1_")
67: KSPSetOptionsPrefix(ksp2,"sys2_")
68: .ve
70: This would enable use of different options for each system, such as
71: .vb
72: -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
73: -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
74: .ve
76: Level: advanced
78: .keywords: KSP, set, options, prefix, database
80: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
81: @*/
82: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
83: {
87: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
88: PCSetOptionsPrefix(ksp->pc,prefix);
89: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
90: return(0);
91: }
92:
95: /*@C
96: KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
97: KSP options in the database.
99: Collective on KSP
101: Input Parameters:
102: + ksp - the Krylov context
103: - prefix - the prefix string to prepend to all KSP option requests
105: Notes:
106: A hyphen (-) must NOT be given at the beginning of the prefix name.
107: The first character of all runtime options is AUTOMATICALLY the hyphen.
109: Level: advanced
111: .keywords: KSP, append, options, prefix, database
113: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
114: @*/
115: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
116: {
120: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
121: PCAppendOptionsPrefix(ksp->pc,prefix);
122: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
123: return(0);
124: }
128: /*@C
129: KSPSetUseFischerGuess - Use the Paul Fischer algorithm, see KSPFischerGuessCreate()
131: Collective on KSP
133: Input Parameters:
134: + ksp - the Krylov context
135: . model - use model 1, model 2 or 0 to turn it off
136: - size - size of subspace used to generate initial guess
138: Options Database:
139: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
141: Level: advanced
143: .keywords: KSP, set, options, prefix, database
145: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerInitialGuess()
146: @*/
147: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
148: {
152: if (ksp->guess) {
153: KSPFischerGuessDestroy(ksp->guess);
154: ksp->guess = PETSC_NULL;
155: }
156: if (model == 1 || model == 2) {
157: KSPFischerGuessCreate(ksp,model,size,&ksp->guess);
158: KSPFischerGuessSetFromOptions(ksp->guess);
159: } else if (model != 0) {
160: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Model must be 1 or 2 (or 0 to turn off guess generation)");
161: }
162: return(0);
163: }
167: /*@C
168: KSPSetFischerGuess - Use the Paul Fischer algorithm created by KSPFischerGuessCreate()
170: Collective on KSP
172: Input Parameters:
173: + ksp - the Krylov context
174: - guess - the object created with KSPFischerGuessCreate()
176: Level: advanced
178: Notes: this allows a single KSP to be used with several different initial guess generators (likely for different linear
179: solvers, see KSPSetPC()).
181: This increases the reference count of the guess object, you must destroy the object with KSPFischerGuessDestroy()
182: before the end of the program.
184: .keywords: KSP, set, options, prefix, database
186: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerGuess()
187: @*/
188: PetscErrorCode KSPSetFischerGuess(KSP ksp,KSPFischerGuess guess)
189: {
193: if (ksp->guess) {
194: KSPFischerGuessDestroy(ksp->guess);
195: }
196: ksp->guess = guess;
197: if (guess) guess->refcnt++;
198: return(0);
199: }
203: /*@C
204: KSPGetFischerGuess - Gets the initial guess generator set with either KSPSetFischerGuess() or KSPCreateFischerGuess()/KSPSetFischerGuess()
206: Collective on KSP
208: Input Parameters:
209: . ksp - the Krylov context
211: Output Parameters:
212: . guess - the object
214: Level: developer
216: .keywords: KSP, set, options, prefix, database
218: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess()
219: @*/
220: PetscErrorCode KSPGetFischerGuess(KSP ksp,KSPFischerGuess *guess)
221: {
223: *guess = ksp->guess;
224: return(0);
225: }
229: /*@C
230: KSPGetOptionsPrefix - Gets the prefix used for searching for all
231: KSP options in the database.
233: Not Collective
235: Input Parameters:
236: . ksp - the Krylov context
238: Output Parameters:
239: . prefix - pointer to the prefix string used is returned
241: Notes: On the fortran side, the user should pass in a string 'prifix' of
242: sufficient length to hold the prefix.
244: Level: advanced
246: .keywords: KSP, set, options, prefix, database
248: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
249: @*/
250: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
251: {
255: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
256: return(0);
257: }
261: /*@
262: KSPSetFromOptions - Sets KSP options from the options database.
263: This routine must be called before KSPSetUp() if the user is to be
264: allowed to set the Krylov type.
266: Collective on KSP
268: Input Parameters:
269: . ksp - the Krylov space context
271: Options Database Keys:
272: + -ksp_max_it - maximum number of linear iterations
273: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
274: if residual norm decreases by this factor than convergence is declared
275: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
276: norm is less than this then convergence is declared
277: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
278: . -ksp_converged_use_initial_residual_norm - see KSPDefaultConvergedSetUIRNorm()
279: . -ksp_converged_use_min_initial_residual_norm - see KSPDefaultConvergedSetUMIRNorm()
280: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
281: $ convergence test (say you always want to run with 5 iterations) to
282: $ save on communication overhead
283: $ preconditioned - default for left preconditioning
284: $ unpreconditioned - see KSPSetNormType()
285: $ natural - see KSPSetNormType()
286: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
287: $ works only for PCBCGS, PCIBCGS and and PCCG
288: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
289: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
290: . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
291: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
292: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
293: . -ksp_monitor <optional filename> - print residual norm at each iteration
294: . -ksp_monitor_draw - plot residual norm at each iteration
295: . -ksp_monitor_solution - plot solution at each iteration
296: - -ksp_monitor_singular_value - monitor extremem singular values at each iteration
298: Notes:
299: To see all options, run your program with the -help option
300: or consult the users manual.
302: Level: beginner
304: .keywords: KSP, set, from, options, database
306: .seealso: KSPSetUseFischerInitialGuess()
308: @*/
309: PetscErrorCode KSPSetFromOptions(KSP ksp)
310: {
311: PetscErrorCode ierr;
312: PetscInt indx;
313: const char *convtests[] = {"default","skip"};
314: char type[256], monfilename[PETSC_MAX_PATH_LEN];
315: PetscViewerASCIIMonitor monviewer;
316: PetscTruth flg,flag;
317: PetscInt i,model[2],nmax = 2;
318: void *ctx;
322: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
323: PCSetFromOptions(ksp->pc);
325: if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
326: PetscOptionsBegin(((PetscObject)ksp)->comm,((PetscObject)ksp)->prefix,"Krylov Method (KSP) Options","KSP");
327: PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name?((PetscObject)ksp)->type_name:KSPGMRES),type,256,&flg);
328: if (flg) {
329: KSPSetType(ksp,type);
330: }
331: /*
332: Set the type if it was never set.
333: */
334: if (!((PetscObject)ksp)->type_name) {
335: KSPSetType(ksp,KSPGMRES);
336: }
338: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
339: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
340: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,PETSC_NULL);
341: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);
343: flag = PETSC_FALSE;
344: PetscOptionsTruth("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPDefaultConvergedSetUIRNorm",flag,&flag,PETSC_NULL);
345: if (flag) {KSPDefaultConvergedSetUIRNorm(ksp);}
346: flag = PETSC_FALSE;
347: PetscOptionsTruth("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPDefaultConvergedSetUMIRNorm",flag,&flag,PETSC_NULL);
348: if (flag) {KSPDefaultConvergedSetUMIRNorm(ksp);}
349: flag = PETSC_FALSE;
350: PetscOptionsTruth("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,PETSC_NULL);
351: if (flag) ksp->guess_zero = PETSC_FALSE;
353: PetscOptionsTruth("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,PETSC_NULL);
354: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorihtm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
355: if (flag) {
356: if (nmax != 2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
357: KSPSetUseFischerGuess(ksp,model[0],model[1]);
358: }
360: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
361: if (flg) {
362: switch (indx) {
363: case 0:
364: KSPDefaultConvergedCreate(&ctx);
365: KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);
366: break;
367: case 1: KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL,PETSC_NULL); break;
368: }
369: }
371: PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,4,"preconditioned",&indx,&flg);
372: if (flg) { KSPSetNormType(ksp,(KSPNormType)indx); }
374: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,PETSC_NULL);
376: flg = PETSC_FALSE;
377: PetscOptionsTruth("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flg,&flg,PETSC_NULL);
378: if (flg) {
379: KSPSetLagNorm(ksp,PETSC_TRUE);
380: }
382: flg = PETSC_FALSE;
383: PetscOptionsTruth("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flg,&flg,PETSC_NULL);
384: if (flg) {
385: KSPSetDiagonalScale(ksp,PETSC_TRUE);
386: }
387: flg = PETSC_FALSE;
388: PetscOptionsTruth("-ksp_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","KSPSetDiagonalScaleFix",flg,&flg,PETSC_NULL);
389: if (flg) {
390: KSPSetDiagonalScaleFix(ksp,PETSC_TRUE);
391: }
393: flg = PETSC_FALSE;
394: PetscOptionsTruth("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,PETSC_NULL);
395: if (flg) {
396: MatNullSpace nsp;
398: MatNullSpaceCreate(((PetscObject)ksp)->comm,PETSC_TRUE,0,0,&nsp);
399: KSPSetNullSpace(ksp,nsp);
400: MatNullSpaceDestroy(nsp);
401: }
403: /* option is actually checked in KSPSetUp(), just here so goes into help message */
404: if (ksp->nullsp) {
405: PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
406: }
408: /*
409: Prints reason for convergence or divergence of each linear solve
410: */
411: flg = PETSC_FALSE;
412: PetscOptionsTruth("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,PETSC_NULL);
413: if (flg) {
414: ksp->printreason = PETSC_TRUE;
415: }
417: flg = PETSC_FALSE;
418: PetscOptionsTruth("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,PETSC_NULL);
419: /* -----------------------------------------------------------------------*/
420: /*
421: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
422: */
423: if (flg) {
424: KSPMonitorCancel(ksp);
425: }
426: /*
427: Prints preconditioned residual norm at each iteration
428: */
429: PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
430: if (flg) {
431: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
432: KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
433: }
434: /*
435: Prints preconditioned residual norm at each iteration
436: */
437: PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
438: if (flg) {
439: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
440: KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
441: }
442: /*
443: Plots the vector solution
444: */
445: flg = PETSC_FALSE;
446: PetscOptionsTruth("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,PETSC_NULL);
447: if (flg) {
448: KSPMonitorSet(ksp,KSPMonitorSolution,PETSC_NULL,PETSC_NULL);
449: }
450: /*
451: Prints preconditioned and true residual norm at each iteration
452: */
453: PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
454: if (flg) {
455: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
456: KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
457: }
458: /*
459: Prints extreme eigenvalue estimates at each iteration
460: */
461: PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
462: if (flg) {
463: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
464: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
465: KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
466: }
467: /*
468: Prints preconditioned residual norm with fewer digits
469: */
470: PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
471: if (flg) {
472: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
473: KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
474: }
475: /*
476: Graphically plots preconditioned residual norm
477: */
478: flg = PETSC_FALSE;
479: PetscOptionsTruth("-ksp_monitor_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
480: if (flg) {
481: KSPMonitorSet(ksp,KSPMonitorLG,PETSC_NULL,PETSC_NULL);
482: }
483: /*
484: Graphically plots preconditioned and true residual norm
485: */
486: flg = PETSC_FALSE;
487: PetscOptionsTruth("-ksp_monitor_draw_true_residual","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
488: if (flg){
489: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,PETSC_NULL,PETSC_NULL);
490: }
491: /*
492: Graphically plots preconditioned residual norm and range of residual element values
493: */
494: flg = PETSC_FALSE;
495: PetscOptionsTruth("-ksp_monitor_range_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
496: if (flg) {
497: KSPMonitorSet(ksp,KSPMonitorLGRange,PETSC_NULL,PETSC_NULL);
498: }
500: /* -----------------------------------------------------------------------*/
502: PetscOptionsTruthGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
503: if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
504: PetscOptionsTruthGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
505: if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
506: PetscOptionsTruthGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
507: if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}
509: flg = PETSC_FALSE;
510: PetscOptionsTruth("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
511: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
512: flg = PETSC_FALSE;
513: PetscOptionsTruth("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
514: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
515: flg = PETSC_FALSE;
516: PetscOptionsTruth("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
517: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
519: for(i = 0; i < numberofsetfromoptions; i++) {
520: (*othersetfromoptions[i])(ksp);
521: }
523: if (ksp->ops->setfromoptions) {
524: (*ksp->ops->setfromoptions)(ksp);
525: }
526: /* actually check in setup this is just here so goes into help message */
527: PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
528: PetscOptionsEnd();
529: return(0);
530: }