Actual source code: itcl.c
petsc-3.14.5 2021-03-03
2: /*
3: Code for setting KSP options from the options database.
4: */
6: #include <petsc/private/kspimpl.h>
7: #include <petscdraw.h>
9: static PetscErrorCode KSPSetupMonitor_Private(KSP ksp, PetscViewer viewer, PetscViewerFormat format, PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,void*), PetscBool useMonitor)
10: {
14: if (useMonitor) {
15: PetscViewerAndFormat *vf;
17: PetscViewerAndFormatCreate(viewer, format, &vf);
18: PetscObjectDereference((PetscObject) viewer);
19: KSPMonitorSet(ksp, monitor, vf, (PetscErrorCode (*)(void**)) PetscViewerAndFormatDestroy);
20: }
21: return(0);
22: }
24: /*@C
25: KSPSetOptionsPrefix - Sets the prefix used for searching for all
26: KSP options in the database.
28: Logically Collective on ksp
30: Input Parameters:
31: + ksp - the Krylov context
32: - prefix - the prefix string to prepend to all KSP option requests
34: Notes:
35: A hyphen (-) must NOT be given at the beginning of the prefix name.
36: The first character of all runtime options is AUTOMATICALLY the
37: hyphen.
39: For example, to distinguish between the runtime options for two
40: different KSP contexts, one could call
41: .vb
42: KSPSetOptionsPrefix(ksp1,"sys1_")
43: KSPSetOptionsPrefix(ksp2,"sys2_")
44: .ve
46: This would enable use of different options for each system, such as
47: .vb
48: -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
49: -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
50: .ve
52: Level: advanced
54: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
55: @*/
56: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
57: {
62: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
63: PCSetOptionsPrefix(ksp->pc,prefix);
64: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
65: return(0);
66: }
68: /*@C
69: KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
70: KSP options in the database.
72: Logically Collective on ksp
74: Input Parameters:
75: + ksp - the Krylov context
76: - prefix - the prefix string to prepend to all KSP option requests
78: Notes:
79: A hyphen (-) must NOT be given at the beginning of the prefix name.
80: The first character of all runtime options is AUTOMATICALLY the hyphen.
82: Level: advanced
84: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
85: @*/
86: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
87: {
92: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
93: PCAppendOptionsPrefix(ksp->pc,prefix);
94: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
95: return(0);
96: }
98: /*@
99: KSPSetUseFischerGuess - Use the Paul Fischer algorithm
101: Logically Collective on ksp
103: Input Parameters:
104: + ksp - the Krylov context
105: . model - use model 1, model 2 or any other number to turn it off
106: - size - size of subspace used to generate initial guess
108: Options Database:
109: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
111: Level: advanced
113: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
114: @*/
115: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
116: {
117: KSPGuess guess;
124: KSPGetGuess(ksp,&guess);
125: KSPGuessSetType(guess,KSPGUESSFISCHER);
126: KSPGuessFischerSetModel(guess,model,size);
127: return(0);
128: }
130: /*@
131: KSPSetGuess - Set the initial guess object
133: Logically Collective on ksp
135: Input Parameters:
136: + ksp - the Krylov context
137: - guess - the object created with KSPGuessCreate()
139: Level: advanced
141: Notes:
142: this allows a single KSP to be used with several different initial guess generators (likely for different linear
143: solvers, see KSPSetPC()).
145: This increases the reference count of the guess object, you must destroy the object with KSPGuessDestroy()
146: before the end of the program.
148: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
149: @*/
150: PetscErrorCode KSPSetGuess(KSP ksp,KSPGuess guess)
151: {
157: PetscObjectReference((PetscObject)guess);
158: KSPGuessDestroy(&ksp->guess);
159: ksp->guess = guess;
160: ksp->guess->ksp = ksp;
161: return(0);
162: }
164: /*@
165: KSPGetGuess - Gets the initial guess generator for the KSP.
167: Not Collective
169: Input Parameters:
170: . ksp - the Krylov context
172: Output Parameters:
173: . guess - the object
175: Level: developer
177: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
178: @*/
179: PetscErrorCode KSPGetGuess(KSP ksp,KSPGuess *guess)
180: {
186: if (!ksp->guess) {
187: const char* prefix;
189: KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
190: PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
191: if (prefix) {
192: PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
193: }
194: ksp->guess->ksp = ksp;
195: }
196: *guess = ksp->guess;
197: return(0);
198: }
200: /*@C
201: KSPGetOptionsPrefix - Gets the prefix used for searching for all
202: KSP options in the database.
204: Not Collective
206: Input Parameters:
207: . ksp - the Krylov context
209: Output Parameters:
210: . prefix - pointer to the prefix string used is returned
212: Notes:
213: On the fortran side, the user should pass in a string 'prefix' of
214: sufficient length to hold the prefix.
216: Level: advanced
218: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
219: @*/
220: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
221: {
226: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
227: return(0);
228: }
230: /*@C
231: KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
233: Collective on ksp
235: Input Parameters:
236: + ksp - KSP object you wish to monitor
237: . name - the monitor type one is seeking
238: . help - message indicating what monitoring is done
239: . manual - manual page for the monitor
240: - monitor - the monitor function, the context for this object is a PetscViewerAndFormat
242: Level: developer
244: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
245: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
246: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
247: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
248: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
249: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
250: PetscOptionsFList(), PetscOptionsEList()
251: @*/
252: PetscErrorCode KSPMonitorSetFromOptions(KSP ksp,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(KSP,PetscInt,PetscReal,PetscViewerAndFormat*))
253: {
254: PetscErrorCode ierr;
255: PetscBool flg;
256: PetscViewer viewer;
257: PetscViewerFormat format;
260: PetscOptionsGetViewer(PetscObjectComm((PetscObject)ksp),((PetscObject)ksp)->options,((PetscObject)ksp)->prefix,name,&viewer,&format,&flg);
261: KSPSetupMonitor_Private(ksp, viewer, format, (PetscErrorCode (*)(KSP,PetscInt,PetscReal,void*)) monitor, flg);
262: return(0);
263: }
265: /*@
266: KSPSetFromOptions - Sets KSP options from the options database.
267: This routine must be called before KSPSetUp() if the user is to be
268: allowed to set the Krylov type.
270: Collective on ksp
272: Input Parameters:
273: . ksp - the Krylov space context
275: Options Database Keys:
276: + -ksp_max_it - maximum number of linear iterations
277: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
278: if residual norm decreases by this factor than convergence is declared
279: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
280: norm is less than this then convergence is declared
281: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
282: . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
283: . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
284: . -ksp_converged_maxits - see KSPConvergedDefaultSetConvergedMaxits()
285: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
286: convergence test (say you always want to run with 5 iterations) to
287: save on communication overhead
288: preconditioned - default for left preconditioning
289: unpreconditioned - see KSPSetNormType()
290: natural - see KSPSetNormType()
291: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
292: works only for PCBCGS, PCIBCGS and and PCCG
293: . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
294: the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
295: This will require 1 more iteration of the solver than usual.
296: . -ksp_guess_type - Type of initial guess generator for repeated linear solves
297: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
298: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
299: . -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
300: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
301: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
302: . -ksp_monitor <optional filename> - print residual norm at each iteration
303: . -ksp_monitor_lg_residualnorm - plot residual norm at each iteration
304: . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
305: - -ksp_monitor_singular_value - monitor extreme singular values at each iteration
307: Notes:
308: To see all options, run your program with the -help option
309: or consult Users-Manual: ch_ksp
311: Level: beginner
313: .seealso: KSPSetOptionsPrefix(), KSPResetFromOptions(), KSPSetUseFischerGuess()
315: @*/
316: PetscErrorCode KSPSetFromOptions(KSP ksp)
317: {
318: const char *convtests[]={"default","skip","lsqr"},*prefix;
319: char type[256],guesstype[256],monfilename[PETSC_MAX_PATH_LEN];
320: PetscBool flg,flag,reuse,set;
321: PetscInt indx,model[2]={0,0},nmax;
322: KSPNormType normtype;
323: PCSide pcside;
324: void *ctx;
325: MPI_Comm comm;
330: PetscObjectGetComm((PetscObject) ksp, &comm);
331: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
332: if (!ksp->skippcsetfromoptions) {
333: if (!ksp->pc) {KSPGetPC(ksp,&ksp->pc);}
334: PCSetFromOptions(ksp->pc);
335: }
337: KSPRegisterAll();
338: PetscObjectOptionsBegin((PetscObject)ksp);
339: PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
340: if (flg) {
341: KSPSetType(ksp,type);
342: }
343: /*
344: Set the type if it was never set.
345: */
346: if (!((PetscObject)ksp)->type_name) {
347: KSPSetType(ksp,KSPGMRES);
348: }
350: KSPResetViewers(ksp);
352: PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
353: if (flg) {
354: KSPGetReusePreconditioner(ksp,&reuse);
355: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
356: KSPSetReusePreconditioner(ksp,reuse);
357: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
358: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer, &ksp->format,&ksp->view);
359: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);
360: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
361: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
362: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
363: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
364: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
365: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
366: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
367: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);
369: KSPGetDiagonalScale(ksp,&flag);
370: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
371: if (flg) {
372: KSPSetDiagonalScale(ksp,flag);
373: }
374: KSPGetDiagonalScaleFix(ksp,&flag);
375: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
376: if (flg) {
377: KSPSetDiagonalScaleFix(ksp,flag);
378: }
379: goto skipoptions;
380: }
382: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);
383: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);
384: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);
385: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);
387: PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
388: if (set && flag) {KSPConvergedDefaultSetUIRNorm(ksp);}
389: 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);
390: if (set && flag) {KSPConvergedDefaultSetUMIRNorm(ksp);}
391: PetscOptionsBool("-ksp_converged_maxits","Declare convergence if the maximum number of iterations is reached","KSPConvergedDefaultSetConvergedMaxits",PETSC_FALSE,&flag,&set);
392: if (set) {KSPConvergedDefaultSetConvergedMaxits(ksp,flag);}
393: 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);
394: if (flg) {
395: KSPSetInitialGuessNonzero(ksp,flag);
396: }
397: KSPGetReusePreconditioner(ksp,&reuse);
398: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
399: KSPSetReusePreconditioner(ksp,reuse);
401: PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
402: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
403: PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
404: if (flg) {
405: KSPGetGuess(ksp,&ksp->guess);
406: KSPGuessSetType(ksp->guess,guesstype);
407: KSPGuessSetFromOptions(ksp->guess);
408: } else { /* old option for KSP */
409: nmax = 2;
410: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
411: if (flag) {
412: if (nmax != 2) SETERRQ(comm,PETSC_ERR_ARG_OUTOFRANGE,"Must pass in model,size as arguments");
413: KSPSetUseFischerGuess(ksp,model[0],model[1]);
414: }
415: }
417: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);
418: if (flg) {
419: switch (indx) {
420: case 0:
421: KSPConvergedDefaultCreate(&ctx);
422: KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
423: break;
424: case 1:
425: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);
426: break;
427: case 2:
428: KSPConvergedDefaultCreate(&ctx);
429: KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);
430: break;
431: }
432: }
434: KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);
435: PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
436: if (flg) { KSPSetNormType(ksp,normtype); }
438: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);
440: PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
441: if (flg) {
442: KSPSetLagNorm(ksp,flag);
443: }
445: KSPGetDiagonalScale(ksp,&flag);
446: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
447: if (flg) {
448: KSPSetDiagonalScale(ksp,flag);
449: }
450: KSPGetDiagonalScaleFix(ksp,&flag);
451: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
452: if (flg) {
453: KSPSetDiagonalScaleFix(ksp,flag);
454: }
456: PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
457: if (set && flg) {
458: MatNullSpace nsp;
459: Mat Amat = NULL;
461: MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);
462: if (ksp->pc) { PCGetOperators(ksp->pc,&Amat,NULL); }
463: if (Amat) {
464: MatSetNullSpace(Amat,nsp);
465: MatNullSpaceDestroy(&nsp);
466: } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
467: }
469: PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
470: /* -----------------------------------------------------------------------*/
471: /*
472: Cancels all monitors hardwired into code before call to KSPSetFromOptions()
473: */
474: if (set && flg) {
475: KSPMonitorCancel(ksp);
476: }
477: KSPMonitorSetFromOptions(ksp,"-ksp_monitor","Monitor the (preconditioned) residual norm","KSPMonitorDefault",KSPMonitorDefault);
478: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_range","Monitor the percentage of large entries in the residual","KSPMonitorRange",KSPMonitorRange);
479: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_true_residual","Monitor the unpreconditioned residual norm","KSPMOnitorTrueResidual",KSPMonitorTrueResidualNorm);
480: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_max","Monitor the maximum norm of the residual","KSPMonitorTrueResidualMaxNorm",KSPMonitorTrueResidualMaxNorm);
481: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_short","Monitor preconditioned residual norm with fewer digits","KSPMonitorDefaultShort",KSPMonitorDefaultShort);
482: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_solution","Monitor the solution","KSPMonitorSolution",KSPMonitorSolution);
483: KSPMonitorSetFromOptions(ksp,"-ksp_monitor_singular_value","Monitor singular values","KSPMonitorSingularValue",KSPMonitorSingularValue);
484: PetscOptionsHasName(NULL,((PetscObject)ksp)->prefix,"-ksp_monitor_singular_value",&flg);
485: if (flg) {
486: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
487: }
488: flg = PETSC_FALSE;
489: if (ksp->pc) {
490: PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
491: if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flg);
492: if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCDEFLATION,&flg);
493: }
495: if (flg) {
496: /* A hack for using dynamic tolerance in preconditioner */
497: PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,sizeof(monfilename),&flg);
498: if (flg) {
499: KSPDynTolCtx *scale;
500: PetscMalloc1(1,&scale);
501: scale->bnrm = -1.0;
502: scale->coef = 1.0;
503: PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
504: KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
505: }
506: }
508: /*
509: Calls Python function
510: */
511: PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);
512: if (flg) {PetscPythonMonitorSet((PetscObject)ksp,monfilename);}
513: /*
514: Graphically plots preconditioned residual norm
515: */
516: PetscOptionsBool("-ksp_monitor_lg_residualnorm","Monitor graphically preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
517: if (set && flg) {
518: PetscDrawLG ctx;
520: KSPMonitorLGResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
521: KSPMonitorSet(ksp,KSPMonitorLGResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
522: }
523: /*
524: Graphically plots preconditioned and true residual norm
525: */
526: PetscOptionsBool("-ksp_monitor_lg_true_residualnorm","Monitor graphically true residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
527: if (set && flg) {
528: PetscDrawLG ctx;
530: KSPMonitorLGTrueResidualNormCreate(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
531: KSPMonitorSet(ksp,KSPMonitorLGTrueResidualNorm,ctx,(PetscErrorCode (*)(void**))PetscDrawLGDestroy);
532: }
533: /*
534: Graphically plots preconditioned residual norm and range of residual element values
535: */
536: PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
537: if (set && flg) {
538: PetscViewer ctx;
540: PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
541: KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
542: }
543: /* TODO Do these show up in help? */
544: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer,&ksp->format,&ksp->view);
545: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre",&ksp->viewerPre,&ksp->formatPre,&ksp->viewPre);
546: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_reason",&ksp->viewerReason,&ksp->formatReason,&ksp->viewReason);
547: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
548: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
549: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
550: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
551: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
552: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
553: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
554: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
555: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
556: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
557: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);
559: /* Deprecated options */
560: if (!ksp->viewEV) {
561: PetscOptionsDeprecated("-ksp_compute_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues");
562: PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
563: }
564: if (!ksp->viewEV) {
565: PetscOptionsDeprecated("-ksp_plot_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues draw");
566: PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
567: if (ksp->viewEV) {
568: ksp->formatEV = PETSC_VIEWER_DEFAULT;
569: ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
570: PetscObjectReference((PetscObject) ksp->viewerEV);
571: }
572: }
573: if (!ksp->viewEV) {
574: PetscOptionsDeprecated("-ksp_plot_eigencontours",NULL,"3.9","Use -ksp_view_eigenvalues draw::draw_contour");
575: PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
576: if (ksp->viewEV) {
577: ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
578: ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
579: PetscObjectReference((PetscObject) ksp->viewerEV);
580: }
581: }
582: if (!ksp->viewEVExp) {
583: PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit");
584: PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
585: }
586: if (!ksp->viewEVExp) {
587: PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit draw");
588: PetscOptionsName("-ksp_plot_eigenvalues_explicitly","[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]","KSPView",&ksp->viewEVExp);
589: if (ksp->viewEVExp) {
590: ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
591: ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
592: PetscObjectReference((PetscObject) ksp->viewerEVExp);
593: }
594: }
595: if (!ksp->viewSV) {
596: PetscOptionsDeprecated("-ksp_compute_singularvalues",NULL,"3.9","Use -ksp_view_singularvalues");
597: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_compute_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
598: }
599: if (!ksp->viewFinalRes) {
600: PetscOptionsDeprecated("-ksp_final_residual",NULL,"3.9","Use -ksp_view_final_residual");
601: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
602: }
604: #if defined(PETSC_HAVE_SAWS)
605: /*
606: Publish convergence information using AMS
607: */
608: PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
609: if (set && flg) {
610: void *ctx;
611: KSPMonitorSAWsCreate(ksp,&ctx);
612: KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
613: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
614: }
615: #endif
617: /* -----------------------------------------------------------------------*/
618: KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
619: PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
620: if (flg) {KSPSetPCSide(ksp,pcside);}
622: if (ksp->viewSV || ksp->viewEV) {
623: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
624: }
626: #if defined(PETSC_HAVE_SAWS)
627: {
628: PetscBool set;
629: flg = PETSC_FALSE;
630: PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
631: if (set) {
632: PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
633: }
634: }
635: #endif
637: nmax = PETSC_DECIDE;
638: PetscOptionsInt("-ksp_matsolve_block_size", "Maximum number of columns treated simultaneously", "KSPMatSolve", nmax, &nmax, &flg);
639: if (flg) {
640: KSPSetMatSolveBlockSize(ksp, nmax);
641: }
643: if (ksp->ops->setfromoptions) {
644: (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
645: }
646: skipoptions:
647: /* process any options handlers added with PetscObjectAddOptionsHandler() */
648: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
649: PetscOptionsEnd();
650: ksp->setfromoptionscalled++;
651: return(0);
652: }
654: /*@
655: KSPResetFromOptions - Sets various KSP parameters from user options ONLY if the KSP was previously set from options
657: Collective on ksp
659: Input Parameter:
660: . ksp - the KSP context
662: Level: beginner
664: .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
665: @*/
666: PetscErrorCode KSPResetFromOptions(KSP ksp)
667: {
671: if (ksp->setfromoptionscalled) {KSPSetFromOptions(ksp);}
672: return(0);
673: }