Actual source code: itcl.c
1: #define PETSCKSP_DLL
3: /*
4: Code for setting KSP options from the options database.
5: */
7: #include src/ksp/ksp/kspimpl.h
8: #include petscsys.h
10: /*
11: We retain a list of functions that also take KSP command
12: line options. These are called at the end KSPSetFromOptions()
13: */
14: #define MAXSETFROMOPTIONS 5
15: PetscInt numberofsetfromoptions = 0;
16: PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(KSP) = {0};
22: /*@C
23: KSPAddOptionsChecker - Adds an additional function to check for KSP options.
25: Not Collective
27: Input Parameter:
28: . kspcheck - function that checks for options
30: Level: developer
32: .keywords: KSP, add, options, checker
34: .seealso: KSPSetFromOptions()
35: @*/
36: PetscErrorCode KSPAddOptionsChecker(PetscErrorCode (*kspcheck)(KSP))
37: {
39: if (numberofsetfromoptions >= MAXSETFROMOPTIONS) {
40: SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Too many options checkers, only 5 allowed");
41: }
43: othersetfromoptions[numberofsetfromoptions++] = kspcheck;
44: return(0);
45: }
49: /*@C
50: KSPSetOptionsPrefix - Sets the prefix used for searching for all
51: KSP options in the database.
53: Collective on KSP
55: Input Parameters:
56: + ksp - the Krylov context
57: - prefix - the prefix string to prepend to all KSP option requests
59: Notes:
60: A hyphen (-) must NOT be given at the beginning of the prefix name.
61: The first character of all runtime options is AUTOMATICALLY the
62: hyphen.
64: For example, to distinguish between the runtime options for two
65: different KSP contexts, one could call
66: .vb
67: KSPSetOptionsPrefix(ksp1,"sys1_")
68: KSPSetOptionsPrefix(ksp2,"sys2_")
69: .ve
71: This would enable use of different options for each system, such as
72: .vb
73: -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
74: -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
75: .ve
77: Level: advanced
79: .keywords: KSP, set, options, prefix, database
81: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
82: @*/
83: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
84: {
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: PCAppendOptionsPrefix(ksp->pc,prefix);
121: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
122: return(0);
123: }
127: /*@C
128: KSPGetOptionsPrefix - Gets the prefix used for searching for all
129: KSP options in the database.
131: Not Collective
133: Input Parameters:
134: . ksp - the Krylov context
136: Output Parameters:
137: . prefix - pointer to the prefix string used is returned
139: Notes: On the fortran side, the user should pass in a string 'prifix' of
140: sufficient length to hold the prefix.
142: Level: advanced
144: .keywords: KSP, set, options, prefix, database
146: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
147: @*/
148: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
149: {
153: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
154: return(0);
155: }
159: /*@
160: KSPSetFromOptions - Sets KSP options from the options database.
161: This routine must be called before KSPSetUp() if the user is to be
162: allowed to set the Krylov type.
164: Collective on KSP
166: Input Parameters:
167: . ksp - the Krylov space context
169: Options Database Keys:
170: + -ksp_max_it - maximum number of linear iterations
171: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
172: if residual norm decreases by this factor than convergence is declared
173: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
174: norm is less than this then convergence is declared
175: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
176: . -ksp_converged_use_initial_residual_norm - see KSPDefaultConvergedSetUIRNorm()
177: . -ksp_converged_use_min_initial_residual_norm - see KSPDefaultConvergedSetUMIRNorm()
178: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
179: $ convergence test (say you always want to run with 5 iterations) to
180: $ save on communication overhead
181: $ preconditioned - default for left preconditioning
182: $ unpreconditioned - see KSPSetNormType()
183: $ natural - see KSPSetNormType()
184: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
185: . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
186: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
187: . -ksp_cancelmonitors - cancel all previous convergene monitor routines set
188: . -ksp_monitor <optional filename> - print residual norm at each iteration
189: . -ksp_xmonitor - plot residual norm at each iteration
190: . -ksp_vecmonitor - plot solution at each iteration
191: - -ksp_singmonitor - monitor extremem singular values at each iteration
193: Notes:
194: To see all options, run your program with the -help option
195: or consult the users manual.
197: Level: beginner
199: .keywords: KSP, set, from, options, database
201: .seealso:
202: @*/
203: PetscErrorCode KSPSetFromOptions(KSP ksp)
204: {
206: PetscInt indx;
207: char type[256], monfilename[PETSC_MAX_PATH_LEN];
208: const char *stype[] = {"none","preconditioned","unpreconditioned","natural"};
209: PetscViewer monviewer;
210: PetscTruth flg,flag;
211: PetscInt i;
215: PCSetFromOptions(ksp->pc);
217: if (!KSPRegisterAllCalled) {KSPRegisterAll(PETSC_NULL);}
218: PetscOptionsBegin(ksp->comm,ksp->prefix,"Krylov Method (KSP) Options","KSP");
219: PetscOptionsList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(ksp->type_name?ksp->type_name:KSPGMRES),type,256,&flg);
220: if (flg) {
221: KSPSetType(ksp,type);
222: }
223: /*
224: Set the type if it was never set.
225: */
226: if (!ksp->type_name) {
227: KSPSetType(ksp,KSPGMRES);
228: }
230: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,PETSC_NULL);
231: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,PETSC_NULL);
232: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,PETSC_NULL);
233: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,PETSC_NULL);
235: PetscOptionsName("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPDefaultConvergedSetUIRNorm",&flag);
236: if (flag) {KSPDefaultConvergedSetUIRNorm(ksp);}
237: PetscOptionsName("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPDefaultConvergedSetUMIRNorm",&flag);
238: if (flag) {KSPDefaultConvergedSetUMIRNorm(ksp);}
240: PetscOptionsTruth("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,
241: &ksp->guess_knoll,PETSC_NULL);
243: PetscOptionsEList("-ksp_norm_type","KSP Norm type","KSPSetNormType",stype,4,"preconditioned",&indx,&flg);
244: if (flg) {
245: switch (indx) {
246: case 0:
247: KSPSetNormType(ksp,KSP_NO_NORM);
248: KSPSetConvergenceTest(ksp,KSPSkipConverged,0);
249: break;
250: case 1:
251: KSPSetNormType(ksp,KSP_PRECONDITIONED_NORM);
252: break;
253: case 2:
254: KSPSetNormType(ksp,KSP_UNPRECONDITIONED_NORM);
255: break;
256: case 3:
257: KSPSetNormType(ksp,KSP_NATURAL_NORM);
258: break;
259: }
260: }
262: PetscOptionsName("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",&flg);
263: if (flg) {
264: KSPSetDiagonalScale(ksp,PETSC_TRUE);
265: }
266: PetscOptionsName("-ksp_diagonal_scale_fix","Fix diagonaled scaled matrix after solve","KSPSetDiagonalScaleFix",&flg);
267: if (flg) {
268: KSPSetDiagonalScaleFix(ksp,PETSC_TRUE);
269: }
272: PetscOptionsName("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",&flg);
273: if (flg) {
274: MatNullSpace nsp;
276: MatNullSpaceCreate(ksp->comm,PETSC_TRUE,0,0,&nsp);
277: KSPSetNullSpace(ksp,nsp);
278: MatNullSpaceDestroy(nsp);
279: }
281: /* option is actually checked in KSPSetUp() */
282: if (ksp->nullsp) {
283: PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
284: }
286: /*
287: Prints reason for convergence or divergence of each linear solve
288: */
289: PetscOptionsName("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",&flg);
290: if (flg) {
291: ksp->printreason = PETSC_TRUE;
292: }
294: PetscOptionsName("-ksp_cancelmonitors","Remove any hardwired monitor routines","KSPClearMonitor",&flg);
295: /* -----------------------------------------------------------------------*/
296: /*
297: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
298: */
299: if (flg) {
300: KSPClearMonitor(ksp);
301: }
302: /*
303: Prints preconditioned residual norm at each iteration
304: */
305: PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
306: if (flg) {
307: PetscViewerASCIIOpen(ksp->comm,monfilename,&monviewer);
308: KSPSetMonitor(ksp,KSPDefaultMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
309: }
310: /*
311: Plots the vector solution
312: */
313: PetscOptionsName("-ksp_vecmonitor","Monitor solution graphically","KSPSetMonitor",&flg);
314: if (flg) {
315: KSPSetMonitor(ksp,KSPVecViewMonitor,PETSC_NULL,PETSC_NULL);
316: }
317: /*
318: Prints preconditioned and true residual norm at each iteration
319: */
320: PetscOptionsString("-ksp_truemonitor","Monitor preconditioned residual norm","KSPSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
321: if (flg) {
322: PetscViewerASCIIOpen(ksp->comm,monfilename,&monviewer);
323: KSPSetMonitor(ksp,KSPTrueMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
324: }
325: /*
326: Prints extreme eigenvalue estimates at each iteration
327: */
328: PetscOptionsString("-ksp_singmonitor","Monitor singular values","KSPSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
329: if (flg) {
330: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
331: PetscViewerASCIIOpen(ksp->comm,monfilename,&monviewer);
332: KSPSetMonitor(ksp,KSPSingularValueMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
333: }
334: /*
335: Prints preconditioned residual norm with fewer digits
336: */
337: PetscOptionsString("-ksp_smonitor","Monitor preconditioned residual norm with fewer digits","KSPSetMonitor","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
338: if (flg) {
339: PetscViewerASCIIOpen(ksp->comm,monfilename,&monviewer);
340: KSPSetMonitor(ksp,KSPDefaultSMonitor,monviewer,(PetscErrorCode (*)(void*))PetscViewerDestroy);
341: }
342: /*
343: Graphically plots preconditioned residual norm
344: */
345: PetscOptionsName("-ksp_xmonitor","Monitor graphically preconditioned residual norm","KSPSetMonitor",&flg);
346: if (flg) {
347: KSPSetMonitor(ksp,KSPLGMonitor,PETSC_NULL,PETSC_NULL);
348: }
349: /*
350: Graphically plots preconditioned and true residual norm
351: */
352: PetscOptionsName("-ksp_xtruemonitor","Monitor graphically true residual norm","KSPSetMonitor",&flg);
353: if (flg){
354: KSPSetMonitor(ksp,KSPLGTrueMonitor,PETSC_NULL,PETSC_NULL);
355: }
357: /* -----------------------------------------------------------------------*/
359: PetscOptionsTruthGroupBegin("-ksp_left_pc","Use left preconditioning","KSPSetPreconditionerSide",&flg);
360: if (flg) { KSPSetPreconditionerSide(ksp,PC_LEFT); }
361: PetscOptionsTruthGroup("-ksp_right_pc","Use right preconditioning","KSPSetPreconditionerSide",&flg);
362: if (flg) { KSPSetPreconditionerSide(ksp,PC_RIGHT);}
363: PetscOptionsTruthGroupEnd("-ksp_symmetric_pc","Use symmetric (factorized) preconditioning","KSPSetPreconditionerSide",&flg);
364: if (flg) { KSPSetPreconditionerSide(ksp,PC_SYMMETRIC);}
366: PetscOptionsName("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",&flg);
367: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
368: PetscOptionsName("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",&flg);
369: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
370: PetscOptionsName("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",&flg);
371: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
373: for(i = 0; i < numberofsetfromoptions; i++) {
374: (*othersetfromoptions[i])(ksp);
375: }
377: if (ksp->ops->setfromoptions) {
378: (*ksp->ops->setfromoptions)(ksp);
379: }
380: PetscOptionsName("-ksp_view","View linear solver parameters","KSPView",&flg);
381: PetscOptionsEnd();
382: return(0);
383: }