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: KSPGetInitialGuessNonzero(ksp,&flag);
350: PetscOptionsTruth("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);
351: if (flg) {
352: KSPSetInitialGuessNonzero(ksp,flag);
353: }
355: PetscOptionsTruth("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,PETSC_NULL);
356: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorihtm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
357: if (flag) {
358: if (nmax != 2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
359: KSPSetUseFischerGuess(ksp,model[0],model[1]);
360: }
362: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
363: if (flg) {
364: switch (indx) {
365: case 0:
366: KSPDefaultConvergedCreate(&ctx);
367: KSPSetConvergenceTest(ksp,KSPDefaultConverged,ctx,KSPDefaultConvergedDestroy);
368: break;
369: case 1: KSPSetConvergenceTest(ksp,KSPSkipConverged,PETSC_NULL,PETSC_NULL); break;
370: }
371: }
373: PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,4,"preconditioned",&indx,&flg);
374: if (flg) { KSPSetNormType(ksp,(KSPNormType)indx); }
376: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,PETSC_NULL);
378: flag = ksp->lagnorm;
379: PetscOptionsTruth("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);
380: if (flg) {
381: KSPSetLagNorm(ksp,flag);
382: }
384: KSPGetDiagonalScale(ksp,&flag);
385: PetscOptionsTruth("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
386: if (flg) {
387: KSPSetDiagonalScale(ksp,flag);
388: }
389: KSPGetDiagonalScaleFix(ksp,&flag);
390: PetscOptionsTruth("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
391: if (flg) {
392: KSPSetDiagonalScaleFix(ksp,flag);
393: }
395: flg = PETSC_FALSE;
396: PetscOptionsTruth("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,PETSC_NULL);
397: if (flg) {
398: MatNullSpace nsp;
400: MatNullSpaceCreate(((PetscObject)ksp)->comm,PETSC_TRUE,0,0,&nsp);
401: KSPSetNullSpace(ksp,nsp);
402: MatNullSpaceDestroy(nsp);
403: }
405: /* option is actually checked in KSPSetUp(), just here so goes into help message */
406: if (ksp->nullsp) {
407: PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
408: }
410: /*
411: Prints reason for convergence or divergence of each linear solve
412: */
413: flg = PETSC_FALSE;
414: PetscOptionsTruth("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,PETSC_NULL);
415: if (flg) {
416: ksp->printreason = PETSC_TRUE;
417: }
419: flg = PETSC_FALSE;
420: PetscOptionsTruth("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,PETSC_NULL);
421: /* -----------------------------------------------------------------------*/
422: /*
423: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
424: */
425: if (flg) {
426: KSPMonitorCancel(ksp);
427: }
428: /*
429: Prints preconditioned residual norm at each iteration
430: */
431: PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
432: if (flg) {
433: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
434: KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
435: }
436: /*
437: Prints preconditioned residual norm at each iteration
438: */
439: PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
440: if (flg) {
441: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
442: KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
443: }
444: /*
445: Plots the vector solution
446: */
447: flg = PETSC_FALSE;
448: PetscOptionsTruth("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,PETSC_NULL);
449: if (flg) {
450: KSPMonitorSet(ksp,KSPMonitorSolution,PETSC_NULL,PETSC_NULL);
451: }
452: /*
453: Prints preconditioned and true residual norm at each iteration
454: */
455: PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
456: if (flg) {
457: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
458: KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
459: }
460: /*
461: Prints extreme eigenvalue estimates at each iteration
462: */
463: PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
464: if (flg) {
465: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
466: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
467: KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
468: }
469: /*
470: Prints preconditioned residual norm with fewer digits
471: */
472: PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
473: if (flg) {
474: PetscViewerASCIIMonitorCreate(((PetscObject)ksp)->comm,monfilename,((PetscObject)ksp)->tablevel,&monviewer);
475: KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void*))PetscViewerASCIIMonitorDestroy);
476: }
477: /*
478: Graphically plots preconditioned residual norm
479: */
480: flg = PETSC_FALSE;
481: PetscOptionsTruth("-ksp_monitor_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
482: if (flg) {
483: KSPMonitorSet(ksp,KSPMonitorLG,PETSC_NULL,PETSC_NULL);
484: }
485: /*
486: Graphically plots preconditioned and true residual norm
487: */
488: flg = PETSC_FALSE;
489: PetscOptionsTruth("-ksp_monitor_draw_true_residual","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
490: if (flg){
491: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,PETSC_NULL,PETSC_NULL);
492: }
493: /*
494: Graphically plots preconditioned residual norm and range of residual element values
495: */
496: flg = PETSC_FALSE;
497: PetscOptionsTruth("-ksp_monitor_range_draw","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,PETSC_NULL);
498: if (flg) {
499: KSPMonitorSet(ksp,KSPMonitorLGRange,PETSC_NULL,PETSC_NULL);
500: }
502: /* -----------------------------------------------------------------------*/
504: PetscOptionsTruthGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
505: if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
506: PetscOptionsTruthGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
507: if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
508: PetscOptionsTruthGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
509: if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}
511: flg = PETSC_FALSE;
512: PetscOptionsTruth("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
513: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
514: flg = PETSC_FALSE;
515: PetscOptionsTruth("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
516: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
517: flg = PETSC_FALSE;
518: PetscOptionsTruth("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,PETSC_NULL);
519: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
521: for(i = 0; i < numberofsetfromoptions; i++) {
522: (*othersetfromoptions[i])(ksp);
523: }
525: if (ksp->ops->setfromoptions) {
526: (*ksp->ops->setfromoptions)(ksp);
527: }
528: /* actually check in setup this is just here so goes into help message */
529: PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
530: PetscOptionsEnd();
531: return(0);
532: }