Actual source code: itcl.c
petsc-3.9.4 2018-09-11
2: /*
3: Code for setting KSP options from the options database.
4: */
6: #include <petsc/private/kspimpl.h>
7: #include <petscdraw.h>
9: /*@C
10: KSPSetOptionsPrefix - Sets the prefix used for searching for all
11: KSP options in the database.
13: Logically Collective on KSP
15: Input Parameters:
16: + ksp - the Krylov context
17: - prefix - the prefix string to prepend to all KSP option requests
19: Notes:
20: A hyphen (-) must NOT be given at the beginning of the prefix name.
21: The first character of all runtime options is AUTOMATICALLY the
22: hyphen.
24: For example, to distinguish between the runtime options for two
25: different KSP contexts, one could call
26: .vb
27: KSPSetOptionsPrefix(ksp1,"sys1_")
28: KSPSetOptionsPrefix(ksp2,"sys2_")
29: .ve
31: This would enable use of different options for each system, such as
32: .vb
33: -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
34: -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
35: .ve
37: Level: advanced
39: .keywords: KSP, set, options, prefix, database
41: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
42: @*/
43: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
44: {
49: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
50: PCSetOptionsPrefix(ksp->pc,prefix);
51: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
52: return(0);
53: }
55: /*@C
56: KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
57: KSP options in the database.
59: Logically Collective on KSP
61: Input Parameters:
62: + ksp - the Krylov context
63: - prefix - the prefix string to prepend to all KSP option requests
65: Notes:
66: A hyphen (-) must NOT be given at the beginning of the prefix name.
67: The first character of all runtime options is AUTOMATICALLY the hyphen.
69: Level: advanced
71: .keywords: KSP, append, options, prefix, database
73: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
74: @*/
75: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
76: {
81: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
82: PCAppendOptionsPrefix(ksp->pc,prefix);
83: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
84: return(0);
85: }
87: /*@
88: KSPGetTabLevel - Gets the number of tabs that ASCII output used by ksp.
90: Not Collective
92: Input Parameter:
93: . ksp - a KSP object.
95: Output Parameter:
96: . tab - the number of tabs
98: Level: developer
100: Notes: this is used in conjunction with KSPSetTabLevel() to manage the output from the KSP and its PC coherently.
103: .seealso: KSPSetTabLevel()
105: @*/
106: PetscErrorCode KSPGetTabLevel(KSP ksp,PetscInt *tab)
107: {
112: PetscObjectGetTabLevel((PetscObject)ksp, tab);
113: return(0);
114: }
116: /*@
117: KSPSetTabLevel - Sets the number of tabs that ASCII output for the ksp andn its pc will use.
119: Not Collective
121: Input Parameters:
122: + ksp - a KSP object
123: - tab - the number of tabs
125: Level: developer
127: Notes: this is used to manage the output from KSP and PC objects that are imbedded in other objects,
128: for example, the KSP object inside a SNES object. By indenting each lower level further the heirarchy
129: of objects is very clear. By setting the KSP object's tab level with KSPSetTabLevel() its PC object
130: automatically receives the same tab level, so that whatever objects the pc might create are tabbed
131: appropriately, too.
133: .seealso: KSPGetTabLevel()
134: @*/
135: PetscErrorCode KSPSetTabLevel(KSP ksp, PetscInt tab)
136: {
141: PetscObjectSetTabLevel((PetscObject)ksp, tab);
142: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
143: /* Do we need a PCSetTabLevel()? */
144: PetscObjectSetTabLevel((PetscObject)ksp->pc, tab);
145: return(0);
146: }
148: /*@
149: KSPSetUseFischerGuess - Use the Paul Fischer algorithm
151: Logically Collective on KSP
153: Input Parameters:
154: + ksp - the Krylov context
155: . model - use model 1, model 2 or any other number to turn it off
156: - size - size of subspace used to generate initial guess
158: Options Database:
159: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
161: Level: advanced
163: .keywords: KSP, set, options, prefix, database
165: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
166: @*/
167: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
168: {
169: KSPGuess guess;
176: KSPGetGuess(ksp,&guess);
177: KSPGuessSetType(guess,KSPGUESSFISCHER);
178: KSPGuessFischerSetModel(guess,model,size);
179: return(0);
180: }
182: /*@
183: KSPSetGuess - Set the initial guess object
185: Logically Collective on KSP
187: Input Parameters:
188: + ksp - the Krylov context
189: - guess - the object created with KSPGuessCreate()
191: Level: advanced
193: Notes: this allows a single KSP to be used with several different initial guess generators (likely for different linear
194: solvers, see KSPSetPC()).
196: This increases the reference count of the guess object, you must destroy the object with KSPGuessDestroy()
197: before the end of the program.
199: .keywords: KSP, set, options, prefix, database
201: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
202: @*/
203: PetscErrorCode KSPSetGuess(KSP ksp,KSPGuess guess)
204: {
210: PetscObjectReference((PetscObject)guess);
211: KSPGuessDestroy(&ksp->guess);
212: ksp->guess = guess;
213: ksp->guess->ksp = ksp;
214: return(0);
215: }
217: /*@
218: KSPGetGuess - Gets the initial guess generator for the KSP.
220: Not Collective
222: Input Parameters:
223: . ksp - the Krylov context
225: Output Parameters:
226: . guess - the object
228: Level: developer
230: .keywords: KSP, set, options, prefix, database
232: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
233: @*/
234: PetscErrorCode KSPGetGuess(KSP ksp,KSPGuess *guess)
235: {
241: if (!ksp->guess) {
242: const char* prefix;
244: KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
245: PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
246: if (prefix) {
247: PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
248: }
249: ksp->guess->ksp = ksp;
250: }
251: *guess = ksp->guess;
252: return(0);
253: }
255: /*@C
256: KSPGetOptionsPrefix - Gets the prefix used for searching for all
257: KSP options in the database.
259: Not Collective
261: Input Parameters:
262: . ksp - the Krylov context
264: Output Parameters:
265: . prefix - pointer to the prefix string used is returned
267: Notes: On the fortran side, the user should pass in a string 'prefix' of
268: sufficient length to hold the prefix.
270: Level: advanced
272: .keywords: KSP, set, options, prefix, database
274: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
275: @*/
276: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
277: {
282: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
283: return(0);
284: }
286: /*@C
287: KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
289: Collective on KSP
291: Input Parameters:
292: + ksp - KSP object you wish to monitor
293: . name - the monitor type one is seeking
294: . help - message indicating what monitoring is done
295: . manual - manual page for the monitor
296: - monitor - the monitor function, the context for this object is a PetscViewerAndFormat
298: Level: developer
300: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
301: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
302: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
303: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
304: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
305: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
306: PetscOptionsFList(), PetscOptionsEList()
307: @*/
308: PetscErrorCode KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat*))
309: {
310: PetscErrorCode ierr;
311: PetscBool flg;
312: PetscViewer viewer;
313: PetscViewerFormat format;
316: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);
317: if (flg) {
318: PetscViewerAndFormat *vf;
319: PetscViewerAndFormatCreate(viewer,format,&vf);
320: PetscObjectDereference((PetscObject)viewer);
321: KSPMonitorSet(ksp,(PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy);
322: }
323: return(0);
324: }
326: /*@
327: KSPSetFromOptions - Sets KSP options from the options database.
328: This routine must be called before KSPSetUp() if the user is to be
329: allowed to set the Krylov type.
331: Collective on KSP
333: Input Parameters:
334: . ksp - the Krylov space context
336: Options Database Keys:
337: + -ksp_max_it - maximum number of linear iterations
338: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
339: if residual norm decreases by this factor than convergence is declared
340: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
341: norm is less than this then convergence is declared
342: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
343: . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
344: . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
345: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
346: convergence test (say you always want to run with 5 iterations) to
347: save on communication overhead
348: preconditioned - default for left preconditioning
349: unpreconditioned - see KSPSetNormType()
350: natural - see KSPSetNormType()
351: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
352: works only for PCBCGS, PCIBCGS and and PCCG
353: . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
354: the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
355: This will require 1 more iteration of the solver than usual.
356: . -ksp_guess_type - Type of initial guess generator for repeated linear solves
357: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
358: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
359: . -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
360: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
361: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
362: . -ksp_monitor <optional filename> - print residual norm at each iteration
363: . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
364: . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
365: - -ksp_monitor_singular_value - monitor extreme singular values at each iteration
367: Notes:
368: To see all options, run your program with the -help option
369: or consult Users-Manual: Chapter 4 KSP: Linear System Solvers
371: Level: beginner
373: .keywords: KSP, set, from, options, database
375: .seealso: KSPSetUseFischerGuess()
377: @*/
378: PetscErrorCode KSPSetFromOptions(KSP ksp)
379: {
381: PetscInt indx;
382: const char *convtests[] = {"default","skip"};
383: char type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN];
384: PetscBool flg,flag,reuse,set;
385: PetscInt model[2]={0,0},nmax;
386: KSPNormType normtype;
387: PCSide pcside;
388: void *ctx;
392: if (!ksp->skippcsetfromoptions) {
393: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
394: PCSetFromOptions(ksp->pc);
395: }
397: KSPRegisterAll();
398: PetscObjectOptionsBegin((PetscObject)ksp);
399: PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
400: if (flg) {
401: KSPSetType(ksp,type);
402: }
403: /*
404: Set the type if it was never set.
405: */
406: if (!((PetscObject)ksp)->type_name) {
407: KSPSetType(ksp,KSPGMRES);
408: }
410: PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
411: if (flg) {
412: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
413: goto skipoptions;
414: }
416: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);
417: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);
418: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);
419: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);
421: PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
422: if (set && flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
423: PetscOptionsBool("-ksp_converged_use_min_initial_residual_norm","Use minimum of initial residual norm and b for computing relative convergence","KSPConvergedDefaultSetUMIRNorm",PETSC_FALSE,&flag,&set);
424: if (set && flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
425: PetscOptionsBool("-ksp_initial_guess_nonzero","Use the contents of the solution vector for initial guess","KSPSetInitialNonzero",ksp->guess_zero ? PETSC_FALSE : PETSC_TRUE,&flag,&flg);
426: if (flg) {
427: KSPSetInitialGuessNonzero(ksp,flag);
428: }
429: PCGetReusePreconditioner(ksp->pc,&reuse);
430: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one ","KSPReusePreconditioner",reuse,&reuse,NULL);
431: KSPSetReusePreconditioner(ksp,reuse);
433: PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
434: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
435: PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
436: if (flg) {
437: KSPGetGuess(ksp,&ksp->guess);
438: KSPGuessSetType(ksp->guess,guesstype);
439: KSPGuessSetFromOptions(ksp->guess);
440: } else { /* old option for KSP */
441: nmax = 2;
442: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
443: if (flag) {
444: if (nmax != 2) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
445: KSPSetUseFischerGuess(ksp,model[0],model[1]);
446: }
447: }
449: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,2,"default",&indx,&flg);
450: if (flg) {
451: switch (indx) {
452: case 0:
453: KSPConvergedDefaultCreate(&ctx);
454: KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
455: break;
456: case 1: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL); break;
457: }
458: }
460: KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);
461: PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
462: if (flg) { KSPSetNormType(ksp,normtype); }
464: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);
466: PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
467: if (flg) {
468: KSPSetLagNorm(ksp,flag);
469: }
471: KSPGetDiagonalScale(ksp,&flag);
472: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
473: if (flg) {
474: KSPSetDiagonalScale(ksp,flag);
475: }
476: KSPGetDiagonalScaleFix(ksp,&flag);
477: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
478: if (flg) {
479: KSPSetDiagonalScaleFix(ksp,flag);
480: }
482: PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
483: if (set && flg) {
484: MatNullSpace nsp;
485: Mat Amat;
487: MatNullSpaceCreate(PetscObjectComm((PetscObject)ksp),PETSC_TRUE,0,NULL,&nsp);
488: PCGetOperators(ksp->pc,&Amat,NULL);
489: if (Amat) {
490: MatSetNullSpace(Amat,nsp);
491: MatNullSpaceDestroy(&nsp);
492: } else SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
493: }
495: PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
496: /* -----------------------------------------------------------------------*/
497: /*
498: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
499: */
500: if (set && flg) {
501: KSPMonitorCancel(ksp);
502: }
503: KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);
504: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);
505: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unprecondiitoned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);
506: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);
507: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);
508: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);
509: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);
510: PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);
511: if (flg) {
512: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
513: }
514: PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
515: PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flag);
517: if (flg || flag) {
518: /* A hack for using dynamic tolerance in preconditioner */
519: PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,PETSC_MAX_PATH_LEN,&flg);
520: if (flg) {
521: KSPDynTolCtx *scale;
522: PetscMalloc1(1,&scale);
523: scale->bnrm = -1.0;
524: scale->coef = 1.0;
525: PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
526: KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
527: }
528: }
529:
531: /*
532: Calls Python function
533: */
534: PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",0,monfilename,PETSC_MAX_PATH_LEN,&flg);
535: if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
536: /*
537: Graphically plots preconditioned residual norm
538: */
539: PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
540: if (set && flg) {
541: PetscDrawLG ctx;
543: KSPMonitorLGResidualNormCreate(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
544: KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
545: }
546: /*
547: Graphically plots preconditioned and true residual norm
548: */
549: PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
550: if (set && flg) {
551: PetscDrawLG ctx;
553: KSPMonitorLGTrueResidualNormCreate(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
554: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
555: }
556: /*
557: Graphically plots preconditioned residual norm and range of residual element values
558: */
559: PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
560: if (set && flg) {
561: PetscViewer ctx;
563: PetscViewerDrawOpen(PetscObjectComm((PetscObject)ksp),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
564: KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
565: }
567: #if defined(PETSC_HAVE_SAWS)
568: /*
569: Publish convergence information using AMS
570: */
571: PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
572: if (set && flg) {
573: void *ctx;
574: KSPMonitorSAWsCreate(ksp,&ctx);
575: KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
576: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
577: }
578: #endif
580: /* -----------------------------------------------------------------------*/
581: KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
582: PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
583: if (flg) {KSPSetPCSide(ksp,pcside);}
585: PetscOptionsBool("-ksp_compute_singularvalues","Compute singular values of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
586: if (set) { KSPSetComputeSingularValues(ksp,flg); }
587: PetscOptionsBool("-ksp_compute_eigenvalues","Compute eigenvalues of preconditioned operator","KSPSetComputeSingularValues",ksp->calc_sings,&flg,&set);
588: if (set) { KSPSetComputeSingularValues(ksp,flg); }
589: PetscOptionsBool("-ksp_plot_eigenvalues","Scatter plot extreme eigenvalues","KSPSetComputeSingularValues",PETSC_FALSE,&flg,&set);
590: if (set) { KSPSetComputeSingularValues(ksp,flg); }
592: #if defined(PETSC_HAVE_SAWS)
593: {
594: PetscBool set;
595: flg = PETSC_FALSE;
596: PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
597: if (set) {
598: PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
599: }
600: }
601: #endif
603: if (ksp->ops->setfromoptions) {
604: (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
605: }
606: skipoptions:
607: /* process any options handlers added with PetscObjectAddOptionsHandler() */
608: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
609: PetscOptionsEnd();
610: return(0);
611: }