Actual source code: itcl.c
petsc-3.5.4 2015-05-23
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: {
52: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
53: PCSetOptionsPrefix(ksp->pc,prefix);
54: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
55: return(0);
56: }
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: {
86: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
87: PCAppendOptionsPrefix(ksp->pc,prefix);
88: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
89: return(0);
90: }
94: /*@
95: KSPGetTabLevel - Gets the number of tabs that ASCII output used by ksp.
97: Not Collective
99: Input Parameter:
100: . ksp - a KSP object.
102: Output Parameter:
103: . tab - the number of tabs
105: Level: developer
107: Notes: this is used in conjunction with KSPSetTabLevel() to manage the output from the KSP and its PC coherently.
110: .seealso: KSPSetTabLevel()
112: @*/
113: PetscErrorCode KSPGetTabLevel(KSP ksp,PetscInt *tab)
114: {
119: PetscObjectGetTabLevel((PetscObject)ksp, tab);
120: return(0);
121: }
125: /*@
126: KSPSetTabLevel - Sets the number of tabs that ASCII output for the ksp andn its pc will use.
128: Not Collective
130: Input Parameters:
131: + ksp - a KSP object
132: - tab - the number of tabs
134: Level: developer
136: Notes: this is used to manage the output from KSP and PC objects that are imbedded in other objects,
137: for example, the KSP object inside a SNES object. By indenting each lower level further the heirarchy
138: of objects is very clear. By setting the KSP object's tab level with KSPSetTabLevel() its PC object
139: automatically receives the same tab level, so that whatever objects the pc might create are tabbed
140: appropriately, too.
142: .seealso: KSPGetTabLevel()
143: @*/
144: PetscErrorCode KSPSetTabLevel(KSP ksp, PetscInt tab)
145: {
150: PetscObjectSetTabLevel((PetscObject)ksp, tab);
151: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
152: /* Do we need a PCSetTabLevel()? */
153: PetscObjectSetTabLevel((PetscObject)ksp->pc, tab);
154: return(0);
155: }
159: /*@C
160: KSPSetUseFischerGuess - Use the Paul Fischer algorithm, see KSPFischerGuessCreate()
162: Logically Collective on KSP
164: Input Parameters:
165: + ksp - the Krylov context
166: . model - use model 1, model 2 or 0 to turn it off
167: - size - size of subspace used to generate initial guess
169: Options Database:
170: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
172: Level: advanced
174: .keywords: KSP, set, options, prefix, database
176: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerInitialGuess()
177: @*/
178: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
179: {
186: KSPFischerGuessDestroy(&ksp->guess);
187: if (model == 1 || model == 2) {
188: KSPFischerGuessCreate(ksp,model,size,&ksp->guess);
189: KSPFischerGuessSetFromOptions(ksp->guess);
190: } else if (model != 0) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Model must be 1 or 2 (or 0 to turn off guess generation)");
191: return(0);
192: }
196: /*@C
197: KSPSetFischerGuess - Use the Paul Fischer algorithm created by KSPFischerGuessCreate()
199: Logically Collective on KSP
201: Input Parameters:
202: + ksp - the Krylov context
203: - guess - the object created with KSPFischerGuessCreate()
205: Level: advanced
207: Notes: this allows a single KSP to be used with several different initial guess generators (likely for different linear
208: solvers, see KSPSetPC()).
210: This increases the reference count of the guess object, you must destroy the object with KSPFischerGuessDestroy()
211: before the end of the program.
213: .keywords: KSP, set, options, prefix, database
215: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess(), KSPGetFischerGuess()
216: @*/
217: PetscErrorCode KSPSetFischerGuess(KSP ksp,KSPFischerGuess guess)
218: {
223: KSPFischerGuessDestroy(&ksp->guess);
224: ksp->guess = guess;
225: if (guess) guess->refcnt++;
226: return(0);
227: }
231: /*@C
232: KSPGetFischerGuess - Gets the initial guess generator set with either KSPSetFischerGuess() or KSPCreateFischerGuess()/KSPSetFischerGuess()
234: Not Collective
236: Input Parameters:
237: . ksp - the Krylov context
239: Output Parameters:
240: . guess - the object
242: Level: developer
244: .keywords: KSP, set, options, prefix, database
246: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetFischerGuess()
247: @*/
248: PetscErrorCode KSPGetFischerGuess(KSP ksp,KSPFischerGuess *guess)
249: {
251: *guess = ksp->guess;
252: return(0);
253: }
257: /*@C
258: KSPGetOptionsPrefix - Gets the prefix used for searching for all
259: KSP options in the database.
261: Not Collective
263: Input Parameters:
264: . ksp - the Krylov context
266: Output Parameters:
267: . prefix - pointer to the prefix string used is returned
269: Notes: On the fortran side, the user should pass in a string 'prifix' of
270: sufficient length to hold the prefix.
272: Level: advanced
274: .keywords: KSP, set, options, prefix, database
276: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
277: @*/
278: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
279: {
284: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
285: return(0);
286: }
290: /*@
291: KSPSetFromOptions - Sets KSP options from the options database.
292: This routine must be called before KSPSetUp() if the user is to be
293: allowed to set the Krylov type.
295: Collective on KSP
297: Input Parameters:
298: . ksp - the Krylov space context
300: Options Database Keys:
301: + -ksp_max_it - maximum number of linear iterations
302: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
303: if residual norm decreases by this factor than convergence is declared
304: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
305: norm is less than this then convergence is declared
306: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
307: . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
308: . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
309: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
310: convergence test (say you always want to run with 5 iterations) to
311: save on communication overhead
312: preconditioned - default for left preconditioning
313: unpreconditioned - see KSPSetNormType()
314: natural - see KSPSetNormType()
315: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
316: works only for PCBCGS, PCIBCGS and and PCCG
317: . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
318: the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
319: This will require 1 more iteration of the solver than usual.
320: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
321: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
322: . -ksp_test_null_space - tests the null space set with KSPSetNullSpace() to see if it truly is a null space
323: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
324: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
325: . -ksp_monitor <optional filename> - print residual norm at each iteration
326: . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
327: . -ksp_monitor_solution - plot solution at each iteration
328: - -ksp_monitor_singular_value - monitor extremem singular values at each iteration
330: Notes:
331: To see all options, run your program with the -help option
332: or consult Users-Manual: Chapter 4 KSP: Linear Equations Solvers
334: Level: beginner
336: .keywords: KSP, set, from, options, database
338: .seealso: KSPSetUseFischerGuess()
340: @*/
341: PetscErrorCode KSPSetFromOptions(KSP ksp)
342: {
344: PetscInt indx;
345: const char *convtests[] = {"default","skip"};
346: char type[256], monfilename[PETSC_MAX_PATH_LEN];
347: PetscViewer monviewer;
348: PetscBool flg,flag,reuse;
349: PetscInt model[2]={0,0},nmax;
350: KSPNormType normtype;
351: PCSide pcside;
352: void *ctx;
356: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
357: PCSetFromOptions(ksp->pc);
359: if (!KSPRegisterAllCalled) {KSPRegisterAll();}
360: PetscObjectOptionsBegin((PetscObject)ksp);
361: PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
362: if (flg) {
363: KSPSetType(ksp,type);
364: }
365: /*
366: Set the type if it was never set.
367: */
368: if (!((PetscObject)ksp)->type_name) {
369: KSPSetType(ksp,KSPGMRES);
370: }
372: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);
373: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);
374: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);
375: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);
377: flag = PETSC_FALSE;
378: PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",flag,&flag,NULL);
379: if (flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
380: flag = PETSC_FALSE;
381: PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",flag,&flag,NULL);
382: if (flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
383: KSPGetInitialGuessNonzero(ksp,&flag);
384: PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",flag,&flag,&flg);
385: if (flg) {
386: KSPSetInitialGuessNonzero(ksp,flag);
387: }
388: PCGetReusePreconditioner(ksp->pc,&reuse);
389: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);
390: KSPSetReusePreconditioner(ksp,reuse);
392: PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
393: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
394: nmax = 2;
395: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
396: if (flag) {
397: if (nmax != 2) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
398: KSPSetUseFischerGuess(ksp,model[0],model[1]);
399: }
401: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
402: if (flg) {
403: switch (indx) {
404: case 0:
405: KSPConvergedDefaultCreate(&ctx);
406: KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
407: break;
408: case 1: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL); break;
409: }
410: }
412: KSPSetUpNorms_Private(ksp,&normtype,&pcside);
413: PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
414: if (flg) { KSPSetNormType(ksp,normtype); }
416: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);
418: flag = ksp->lagnorm;
419: PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",flag,&flag,&flg);
420: if (flg) {
421: KSPSetLagNorm(ksp,flag);
422: }
424: KSPGetDiagonalScale(ksp,&flag);
425: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
426: if (flg) {
427: KSPSetDiagonalScale(ksp,flag);
428: }
429: KSPGetDiagonalScaleFix(ksp,&flag);
430: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
431: if (flg) {
432: KSPSetDiagonalScaleFix(ksp,flag);
433: }
435: flg = PETSC_FALSE;
436: PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver","KSPSetNullSpace",flg,&flg,NULL);
437: if (flg) {
438: MatNullSpace nsp;
440: MatNullSpaceCreate(PetscObjectComm((PetscObject)ksp),PETSC_TRUE,0,0,&nsp);
441: KSPSetNullSpace(ksp,nsp);
442: MatNullSpaceDestroy(&nsp);
443: }
445: /* option is actually checked in KSPSetUp(), just here so goes into help message */
446: if (ksp->nullsp) {
447: PetscOptionsName("-ksp_test_null_space","Is provided null space correct","None",&flg);
448: }
450: /*
451: Prints reason for convergence or divergence of each linear solve
452: */
453: flg = PETSC_FALSE;
454: PetscOptionsBool("-ksp_converged_reason","Print reason for converged or diverged","KSPSolve",flg,&flg,NULL);
455: if (flg) ksp->printreason = PETSC_TRUE;
457: flg = PETSC_FALSE;
458: PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",flg,&flg,NULL);
459: /* -----------------------------------------------------------------------*/
460: /*
461: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
462: */
463: if (flg) {
464: KSPMonitorCancel(ksp);
465: }
466: /*
467: Prints preconditioned residual norm at each iteration
468: */
469: PetscOptionsString("-ksp_monitor","Monitor preconditioned residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
470: if (flg) {
471: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
472: KSPMonitorSet(ksp,KSPMonitorDefault,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
473: }
474: /*
475: Prints preconditioned residual norm at each iteration
476: */
477: PetscOptionsString("-ksp_monitor_range","Monitor percent of residual entries more than 10 percent of max","KSPMonitorRange","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
478: if (flg) {
479: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
480: KSPMonitorSet(ksp,KSPMonitorRange,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
481: }
482: PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
483: PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);
484: if (flg || flag) {
485: /* A hack for using dynamic tolerance in preconditioner */
486: PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
487: if (flg) {
488: KSPDynTolCtx *scale = NULL;
489: PetscReal defaultv = 1.0;
490: PetscMalloc1(1,&scale);
491: scale->bnrm = -1.0;
492: scale->coef = defaultv;
493: PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",defaultv,&(scale->coef),&flg);
494: KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
495: }
496: }
497: /*
498: Plots the vector solution
499: */
500: flg = PETSC_FALSE;
501: PetscOptionsBool("-ksp_monitor_solution","Monitor solution graphically","KSPMonitorSet",flg,&flg,NULL);
502: if (flg) {
503: KSPMonitorSet(ksp,KSPMonitorSolution,NULL,NULL);
504: }
505: /*
506: Prints preconditioned and true residual norm at each iteration
507: */
508: PetscOptionsString("-ksp_monitor_true_residual","Monitor true residual norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
509: if (flg) {
510: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
511: KSPMonitorSet(ksp,KSPMonitorTrueResidualNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
512: }
513: /*
514: Prints with max norm at each iteration
515: */
516: PetscOptionsString("-ksp_monitor_max","Monitor true residual max norm","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
517: if (flg) {
518: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
519: KSPMonitorSet(ksp,KSPMonitorTrueResidualMaxNorm,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
520: }
521: /*
522: Prints extreme eigenvalue estimates at each iteration
523: */
524: PetscOptionsString("-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
525: if (flg) {
526: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
527: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
528: KSPMonitorSet(ksp,KSPMonitorSingularValue,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
529: }
530: /*
531: Prints preconditioned residual norm with fewer digits
532: */
533: PetscOptionsString("-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorSet","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
534: if (flg) {
535: PetscViewerASCIIOpen(PetscObjectComm((PetscObject)ksp),monfilename,&monviewer);
536: KSPMonitorSet(ksp,KSPMonitorDefaultShort,monviewer,(PetscErrorCode (*)(void**))PetscViewerDestroy);
537: }
538: /*
539: Calls Python function
540: */
541: PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
542: if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
543: /*
544: Graphically plots preconditioned residual norm
545: */
546: flg = PETSC_FALSE;
547: PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);
548: if (flg) {
549: PetscDrawLG ctx;
551: KSPMonitorLGResidualNormCreate(0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);
552: KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGResidualNormDestroy);
553: }
554: /*
555: Graphically plots preconditioned and true residual norm
556: */
557: flg = PETSC_FALSE;
558: PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",flg,&flg,NULL);
559: if (flg) {
560: PetscDrawLG ctx;
562: KSPMonitorLGTrueResidualNormCreate(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);
563: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))KSPMonitorLGTrueResidualNormDestroy);
564: }
565: /*
566: Graphically plots preconditioned residual norm and range of residual element values
567: */
568: flg = PETSC_FALSE;
569: PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",flg,&flg,NULL);
570: if (flg) {
571: PetscViewer ctx;
573: PetscViewerDrawOpen(PetscObjectComm((PetscObject)ksp),0,0,PETSC_DECIDE,PETSC_DECIDE,300,300,&ctx);
574: KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
575: }
577: #if defined(PETSC_HAVE_SAWS)
578: /*
579: Publish convergence information using AMS
580: */
581: flg = PETSC_FALSE;
582: PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",flg,&flg,NULL);
583: if (flg) {
584: void *ctx;
585: KSPMonitorSAWsCreate(ksp,&ctx);
586: KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
587: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
588: }
589: #endif
591: /* -----------------------------------------------------------------------*/
592: KSPSetUpNorms_Private(ksp,&normtype,&pcside);
593: PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
594: if (flg) {KSPSetPCSide(ksp,pcside);}
596: flg = PETSC_FALSE;
597: PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);
598: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
599: flg = PETSC_FALSE;
600: PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",flg,&flg,NULL);
601: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
602: flg = PETSC_FALSE;
603: PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",flg,&flg,NULL);
604: if (flg) { KSPSetComputeSingularValues(ksp,PETSC_TRUE); }
606: #if defined(PETSC_HAVE_SAWS)
607: {
608: PetscBool set;
609: flg = PETSC_FALSE;
610: PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
611: if (set) {
612: PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
613: }
614: }
615: #endif
617: if (ksp->ops->setfromoptions) {
618: (*ksp->ops->setfromoptions)(ksp);
619: }
620: /* process any options handlers added with PetscObjectAddOptionsHandler() */
621: PetscObjectProcessOptionsHandlers((PetscObject)ksp);
622: PetscOptionsEnd();
623: return(0);
624: }