Actual source code: itcl.c
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: .seealso: KSPAppendOptionsPrefix(), KSPGetOptionsPrefix()
40: @*/
41: PetscErrorCode KSPSetOptionsPrefix(KSP ksp,const char prefix[])
42: {
44: if (!ksp->pc) KSPGetPC(ksp,&ksp->pc);
45: PCSetOptionsPrefix(ksp->pc,prefix);
46: PetscObjectSetOptionsPrefix((PetscObject)ksp,prefix);
47: return 0;
48: }
50: /*@C
51: KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
52: KSP options in the database.
54: Logically Collective on ksp
56: Input Parameters:
57: + ksp - the Krylov context
58: - prefix - the prefix string to prepend to all KSP option requests
60: Notes:
61: A hyphen (-) must NOT be given at the beginning of the prefix name.
62: The first character of all runtime options is AUTOMATICALLY the hyphen.
64: Level: advanced
66: .seealso: KSPSetOptionsPrefix(), KSPGetOptionsPrefix()
67: @*/
68: PetscErrorCode KSPAppendOptionsPrefix(KSP ksp,const char prefix[])
69: {
71: if (!ksp->pc) KSPGetPC(ksp,&ksp->pc);
72: PCAppendOptionsPrefix(ksp->pc,prefix);
73: PetscObjectAppendOptionsPrefix((PetscObject)ksp,prefix);
74: return 0;
75: }
77: /*@
78: KSPSetUseFischerGuess - Use the Paul Fischer algorithm or its variants
80: Logically Collective on ksp
82: Input Parameters:
83: + ksp - the Krylov context
84: . model - use model 1, model 2, model 3, or any other number to turn it off
85: - size - size of subspace used to generate initial guess
87: Options Database:
88: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
90: Level: advanced
92: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess(), KSPGetGuess()
93: @*/
94: PetscErrorCode KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)
95: {
96: KSPGuess guess;
101: KSPGetGuess(ksp,&guess);
102: KSPGuessSetType(guess,KSPGUESSFISCHER);
103: KSPGuessFischerSetModel(guess,model,size);
104: return 0;
105: }
107: /*@
108: KSPSetGuess - Set the initial guess object
110: Logically Collective on ksp
112: Input Parameters:
113: + ksp - the Krylov context
114: - guess - the object created with KSPGuessCreate()
116: Level: advanced
118: Notes:
119: this allows a single KSP to be used with several different initial guess generators (likely for different linear
120: solvers, see KSPSetPC()).
122: This increases the reference count of the guess object, you must destroy the object with KSPGuessDestroy()
123: before the end of the program.
125: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPGetGuess()
126: @*/
127: PetscErrorCode KSPSetGuess(KSP ksp,KSPGuess guess)
128: {
131: PetscObjectReference((PetscObject)guess);
132: KSPGuessDestroy(&ksp->guess);
133: ksp->guess = guess;
134: ksp->guess->ksp = ksp;
135: return 0;
136: }
138: /*@
139: KSPGetGuess - Gets the initial guess generator for the KSP.
141: Not Collective
143: Input Parameters:
144: . ksp - the Krylov context
146: Output Parameters:
147: . guess - the object
149: Level: developer
151: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix(), KSPSetUseFischerGuess(), KSPSetGuess()
152: @*/
153: PetscErrorCode KSPGetGuess(KSP ksp,KSPGuess *guess)
154: {
157: if (!ksp->guess) {
158: const char* prefix;
160: KSPGuessCreate(PetscObjectComm((PetscObject)ksp),&ksp->guess);
161: PetscObjectGetOptionsPrefix((PetscObject)ksp,&prefix);
162: if (prefix) {
163: PetscObjectSetOptionsPrefix((PetscObject)ksp->guess,prefix);
164: }
165: ksp->guess->ksp = ksp;
166: }
167: *guess = ksp->guess;
168: return 0;
169: }
171: /*@C
172: KSPGetOptionsPrefix - Gets the prefix used for searching for all
173: KSP options in the database.
175: Not Collective
177: Input Parameters:
178: . ksp - the Krylov context
180: Output Parameters:
181: . prefix - pointer to the prefix string used is returned
183: Notes:
184: On the fortran side, the user should pass in a string 'prefix' of
185: sufficient length to hold the prefix.
187: Level: advanced
189: .seealso: KSPSetOptionsPrefix(), KSPAppendOptionsPrefix()
190: @*/
191: PetscErrorCode KSPGetOptionsPrefix(KSP ksp,const char *prefix[])
192: {
194: PetscObjectGetOptionsPrefix((PetscObject)ksp,prefix);
195: return 0;
196: }
198: static PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer viewer, PetscViewerFormat format, void *ctx, PetscViewerAndFormat **vf)
199: {
200: PetscViewerAndFormatCreate(viewer, format, vf);
201: (*vf)->data = ctx;
202: return 0;
203: }
205: /*@C
206: KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user
208: Collective on ksp
210: Input Parameters:
211: + ksp - KSP object you wish to monitor
212: . opt - the command line option for this monitor
213: . name - the monitor type one is seeking
214: - ctx - An optional user context for the monitor, or NULL
216: Level: developer
218: .seealso: PetscOptionsGetViewer(), PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(),
219: PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool()
220: PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(),
221: PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(),
222: PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(),
223: PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(),
224: PetscOptionsFList(), PetscOptionsEList()
225: @*/
226: PetscErrorCode KSPMonitorSetFromOptions(KSP ksp, const char opt[], const char name[], void *ctx)
227: {
228: PetscErrorCode (*mfunc)(KSP, PetscInt, PetscReal, void *);
229: PetscErrorCode (*cfunc)(PetscViewer, PetscViewerFormat, void *, PetscViewerAndFormat **);
230: PetscErrorCode (*dfunc)(PetscViewerAndFormat **);
231: PetscViewerAndFormat *vf;
232: PetscViewer viewer;
233: PetscViewerFormat format;
234: PetscViewerType vtype;
235: char key[PETSC_MAX_PATH_LEN];
236: PetscBool all, flg;
237: const char *prefix = NULL;
239: PetscStrcmp(opt, "-all_ksp_monitor", &all);
240: if (!all) PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
241: PetscOptionsGetViewer(PetscObjectComm((PetscObject) ksp), ((PetscObject) ksp)->options, prefix, opt, &viewer, &format, &flg);
242: if (!flg) return 0;
244: PetscViewerGetType(viewer, &vtype);
245: KSPMonitorMakeKey_Internal(name, vtype, format, key);
246: PetscFunctionListFind(KSPMonitorList, key, &mfunc);
247: PetscFunctionListFind(KSPMonitorCreateList, key, &cfunc);
248: PetscFunctionListFind(KSPMonitorDestroyList, key, &dfunc);
249: if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
250: if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
252: (*cfunc)(viewer, format, ctx, &vf);
253: PetscObjectDereference((PetscObject) viewer);
254: KSPMonitorSet(ksp, mfunc, vf, (PetscErrorCode (*)(void **)) dfunc);
255: return 0;
256: }
258: /*@
259: KSPSetFromOptions - Sets KSP options from the options database.
260: This routine must be called before KSPSetUp() if the user is to be
261: allowed to set the Krylov type.
263: Collective on ksp
265: Input Parameter:
266: . ksp - the Krylov space context
268: Options Database Keys:
269: + -ksp_max_it - maximum number of linear iterations
270: . -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
271: if residual norm decreases by this factor than convergence is declared
272: . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
273: norm is less than this then convergence is declared
274: . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
275: . -ksp_converged_use_initial_residual_norm - see KSPConvergedDefaultSetUIRNorm()
276: . -ksp_converged_use_min_initial_residual_norm - see KSPConvergedDefaultSetUMIRNorm()
277: . -ksp_converged_maxits - see KSPConvergedDefaultSetConvergedMaxits()
278: . -ksp_norm_type - none - skip norms used in convergence tests (useful only when not using
279: convergence test (say you always want to run with 5 iterations) to
280: save on communication overhead
281: preconditioned - default for left preconditioning
282: unpreconditioned - see KSPSetNormType()
283: natural - see KSPSetNormType()
284: . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
285: works only for PCBCGS, PCIBCGS and and PCCG
286: . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration; this means that one can use
287: the norm of the residual for convergence test WITHOUT an extra MPI_Allreduce() limiting global synchronizations.
288: This will require 1 more iteration of the solver than usual.
289: . -ksp_guess_type - Type of initial guess generator for repeated linear solves
290: . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
291: . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
292: . -ksp_test_null_space - tests the null space set with MatSetNullSpace() to see if it truly is a null space
293: . -ksp_knoll - compute initial guess by applying the preconditioner to the right hand side
294: . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
295: . -ksp_monitor - print residual norm at each iteration
296: . -ksp_monitor draw::draw_lg - plot residual norm at each iteration
297: . -ksp_monitor_true_residual - print true residual norm at each iteration
298: . -all_ksp_monitor <optional filename> - print residual norm at each iteration for ALL KSP solves, regardless of their prefix. This is
299: useful for PCFIELDSPLIT, PCMG, etc that have inner solvers and you wish to track the convergence of all the solvers
300: . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
301: . -ksp_monitor_singular_value - monitor extreme singular values at each iteration
302: . -ksp_converged_reason - view the convergence state at the end of the solve
303: . -ksp_use_explicittranspose - transpose the system explicitly in KSPSolveTranspose
304: . -ksp_error_if_not_converged - stop the program as soon as an error is detected in a KSPSolve(), KSP_DIVERGED_ITS is not treated as an error on inner KSPSolves
305: - -ksp_converged_rate - view the convergence rate at the end of the solve
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;
329: PetscObjectGetComm((PetscObject) ksp, &comm);
330: PetscObjectGetOptionsPrefix((PetscObject) ksp, &prefix);
331: if (!ksp->skippcsetfromoptions) {
332: if (!ksp->pc) KSPGetPC(ksp,&ksp->pc);
333: PCSetFromOptions(ksp->pc);
334: }
336: KSPRegisterAll();
337: PetscObjectOptionsBegin((PetscObject)ksp);
338: PetscOptionsFList("-ksp_type","Krylov method","KSPSetType",KSPList,(char*)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES),type,256,&flg);
339: if (flg) {
340: KSPSetType(ksp,type);
341: }
342: /*
343: Set the type if it was never set.
344: */
345: if (!((PetscObject)ksp)->type_name) {
346: KSPSetType(ksp,KSPGMRES);
347: }
349: KSPResetViewers(ksp);
351: /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */
352: PetscOptionsBool("-ksp_monitor_cancel","Remove any hardwired monitor routines","KSPMonitorCancel",PETSC_FALSE,&flg,&set);
353: if (set && flg) KSPMonitorCancel(ksp);
354: KSPMonitorSetFromOptions(ksp, "-ksp_monitor", "preconditioned_residual", NULL);
355: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_short", "preconditioned_residual_short", NULL);
356: KSPMonitorSetFromOptions(ksp, "-all_ksp_monitor", "preconditioned_residual", NULL);
357: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_range", "preconditioned_residual_range", NULL);
358: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_true_residual", "true_residual", NULL);
359: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_max", "true_residual_max", NULL);
360: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_solution", "solution", NULL);
361: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_singular_value", "singular_value", ksp);
362: KSPMonitorSetFromOptions(ksp, "-ksp_monitor_error", "error", ksp);
363: PetscOptionsBool("-ksp_monitor_pause_final", "Pauses all draw monitors at the final iterate", "KSPMonitorPauseFinal_Internal", PETSC_FALSE, &ksp->pauseFinal, NULL);
364: 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);
365: if (flg) {
366: KSPSetInitialGuessNonzero(ksp,flag);
367: }
369: PetscObjectTypeCompare((PetscObject)ksp,KSPPREONLY,&flg);
370: if (flg) {
371: KSPGetReusePreconditioner(ksp,&reuse);
372: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
373: KSPSetReusePreconditioner(ksp,reuse);
374: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
375: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer, &ksp->format,&ksp->view);
376: flg = PETSC_FALSE;
377: PetscOptionsBool("-ksp_converged_reason_view_cancel","Cancel all the converged reason view functions set using KSPConvergedReasonViewSet","KSPConvergedReasonViewCancel",PETSC_FALSE,&flg,&set);
378: if (set && flg) {
379: KSPConvergedReasonViewCancel(ksp);
380: }
381: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
382: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
383: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
384: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
385: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
386: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
387: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
388: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);
390: KSPGetDiagonalScale(ksp,&flag);
391: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
392: if (flg) {
393: KSPSetDiagonalScale(ksp,flag);
394: }
395: KSPGetDiagonalScaleFix(ksp,&flag);
396: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
397: if (flg) {
398: KSPSetDiagonalScaleFix(ksp,flag);
399: }
400: nmax = ksp->nmax;
401: PetscOptionsDeprecated("-ksp_matsolve_block_size","-ksp_matsolve_batch_size","3.15",NULL);
402: PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
403: if (flg) {
404: KSPSetMatSolveBatchSize(ksp, nmax);
405: }
406: goto skipoptions;
407: }
409: PetscOptionsInt("-ksp_max_it","Maximum number of iterations","KSPSetTolerances",ksp->max_it,&ksp->max_it,NULL);
410: PetscOptionsReal("-ksp_rtol","Relative decrease in residual norm","KSPSetTolerances",ksp->rtol,&ksp->rtol,NULL);
411: PetscOptionsReal("-ksp_atol","Absolute value of residual norm","KSPSetTolerances",ksp->abstol,&ksp->abstol,NULL);
412: PetscOptionsReal("-ksp_divtol","Residual norm increase cause divergence","KSPSetTolerances",ksp->divtol,&ksp->divtol,NULL);
414: PetscOptionsBool("-ksp_converged_use_initial_residual_norm","Use initial residual norm for computing relative convergence","KSPConvergedDefaultSetUIRNorm",PETSC_FALSE,&flag,&set);
415: if (set && flag) KSPConvergedDefaultSetUIRNorm(ksp);
416: 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);
417: if (set && flag) KSPConvergedDefaultSetUMIRNorm(ksp);
418: PetscOptionsBool("-ksp_converged_maxits","Declare convergence if the maximum number of iterations is reached","KSPConvergedDefaultSetConvergedMaxits",PETSC_FALSE,&flag,&set);
419: if (set) KSPConvergedDefaultSetConvergedMaxits(ksp,flag);
420: KSPGetReusePreconditioner(ksp,&reuse);
421: PetscOptionsBool("-ksp_reuse_preconditioner","Use initial preconditioner and don't ever compute a new one","KSPReusePreconditioner",reuse,&reuse,NULL);
422: KSPSetReusePreconditioner(ksp,reuse);
424: PetscOptionsBool("-ksp_knoll","Use preconditioner applied to b for initial guess","KSPSetInitialGuessKnoll",ksp->guess_knoll,&ksp->guess_knoll,NULL);
425: PetscOptionsBool("-ksp_error_if_not_converged","Generate error if solver does not converge","KSPSetErrorIfNotConverged",ksp->errorifnotconverged,&ksp->errorifnotconverged,NULL);
426: PetscOptionsFList("-ksp_guess_type","Initial guess in Krylov method",NULL,KSPGuessList,NULL,guesstype,256,&flg);
427: if (flg) {
428: KSPGetGuess(ksp,&ksp->guess);
429: KSPGuessSetType(ksp->guess,guesstype);
430: KSPGuessSetFromOptions(ksp->guess);
431: } else { /* old option for KSP */
432: nmax = 2;
433: PetscOptionsIntArray("-ksp_fischer_guess","Use Paul Fischer's algorithm or its variants for initial guess","KSPSetUseFischerGuess",model,&nmax,&flag);
434: if (flag) {
436: KSPSetUseFischerGuess(ksp,model[0],model[1]);
437: }
438: }
440: PetscOptionsEList("-ksp_convergence_test","Convergence test","KSPSetConvergenceTest",convtests,3,"default",&indx,&flg);
441: if (flg) {
442: switch (indx) {
443: case 0:
444: KSPConvergedDefaultCreate(&ctx);
445: KSPSetConvergenceTest(ksp,KSPConvergedDefault,ctx,KSPConvergedDefaultDestroy);
446: break;
447: case 1:
448: KSPSetConvergenceTest(ksp,KSPConvergedSkip,NULL,NULL);
449: break;
450: case 2:
451: KSPConvergedDefaultCreate(&ctx);
452: KSPSetConvergenceTest(ksp,KSPLSQRConvergedDefault,ctx,KSPConvergedDefaultDestroy);
453: break;
454: }
455: }
457: KSPSetUpNorms_Private(ksp,PETSC_FALSE,&normtype,NULL);
458: PetscOptionsEnum("-ksp_norm_type","KSP Norm type","KSPSetNormType",KSPNormTypes,(PetscEnum)normtype,(PetscEnum*)&normtype,&flg);
459: if (flg) KSPSetNormType(ksp,normtype);
461: PetscOptionsInt("-ksp_check_norm_iteration","First iteration to compute residual norm","KSPSetCheckNormIteration",ksp->chknorm,&ksp->chknorm,NULL);
463: PetscOptionsBool("-ksp_lag_norm","Lag the calculation of the residual norm","KSPSetLagNorm",ksp->lagnorm,&flag,&flg);
464: if (flg) {
465: KSPSetLagNorm(ksp,flag);
466: }
468: KSPGetDiagonalScale(ksp,&flag);
469: PetscOptionsBool("-ksp_diagonal_scale","Diagonal scale matrix before building preconditioner","KSPSetDiagonalScale",flag,&flag,&flg);
470: if (flg) {
471: KSPSetDiagonalScale(ksp,flag);
472: }
473: KSPGetDiagonalScaleFix(ksp,&flag);
474: PetscOptionsBool("-ksp_diagonal_scale_fix","Fix diagonally scaled matrix after solve","KSPSetDiagonalScaleFix",flag,&flag,&flg);
475: if (flg) {
476: KSPSetDiagonalScaleFix(ksp,flag);
477: }
479: PetscOptionsBool("-ksp_constant_null_space","Add constant null space to Krylov solver matrix","MatSetNullSpace",PETSC_FALSE,&flg,&set);
480: if (set && flg) {
481: MatNullSpace nsp;
482: Mat Amat = NULL;
484: MatNullSpaceCreate(comm,PETSC_TRUE,0,NULL,&nsp);
485: if (ksp->pc) PCGetOperators(ksp->pc,&Amat,NULL);
486: if (Amat) {
487: MatSetNullSpace(Amat,nsp);
488: MatNullSpaceDestroy(&nsp);
489: } else SETERRQ(comm,PETSC_ERR_ARG_WRONGSTATE,"Cannot set nullspace, matrix has not yet been provided");
490: }
492: flg = PETSC_FALSE;
493: if (ksp->pc) {
494: PetscObjectTypeCompare((PetscObject)ksp->pc,PCKSP,&flg);
495: if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCBJACOBI,&flg);
496: if (!flg) PetscObjectTypeCompare((PetscObject)ksp->pc,PCDEFLATION,&flg);
497: }
499: if (flg) {
500: /* A hack for using dynamic tolerance in preconditioner */
501: PetscOptionsString("-sub_ksp_dynamic_tolerance","Use dynamic tolerance for PC if PC is a KSP","KSPMonitorDynamicTolerance","stdout",monfilename,sizeof(monfilename),&flg);
502: if (flg) {
503: KSPDynTolCtx *scale;
504: PetscMalloc1(1,&scale);
505: scale->bnrm = -1.0;
506: scale->coef = 1.0;
507: PetscOptionsReal("-sub_ksp_dynamic_tolerance_param","Parameter of dynamic tolerance for inner PCKSP","KSPMonitorDynamicToleranceParam",scale->coef,&scale->coef,&flg);
508: KSPMonitorSet(ksp,KSPMonitorDynamicTolerance,scale,KSPMonitorDynamicToleranceDestroy);
509: }
510: }
512: /*
513: Calls Python function
514: */
515: PetscOptionsString("-ksp_monitor_python","Use Python function","KSPMonitorSet",NULL,monfilename,sizeof(monfilename),&flg);
516: if (flg) PetscPythonMonitorSet((PetscObject)ksp,monfilename);
517: /*
518: Graphically plots preconditioned residual norm and range of residual element values
519: */
520: PetscOptionsBool("-ksp_monitor_lg_range","Monitor graphically range of preconditioned residual norm","KSPMonitorSet",PETSC_FALSE,&flg,&set);
521: if (set && flg) {
522: PetscViewer ctx;
524: PetscViewerDrawOpen(comm,NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx);
525: KSPMonitorSet(ksp,KSPMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy);
526: }
527: /* TODO Do these show up in help? */
528: PetscOptionsHasName(((PetscObject) ksp)->options, prefix, "-ksp_converged_rate", &flg);
529: if (flg) {
530: const char *RateTypes[] = {"default", "residual", "error", "PetscRateType", "RATE_", NULL};
531: PetscEnum rtype = (PetscEnum) 1;
533: PetscOptionsGetEnum(((PetscObject) ksp)->options, prefix, "-ksp_converged_rate_type", RateTypes, &rtype, &flg);
534: if (rtype == (PetscEnum) 0 || rtype == (PetscEnum) 1) KSPSetResidualHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
535: if (rtype == (PetscEnum) 0 || rtype == (PetscEnum) 2) KSPSetErrorHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE);
536: }
537: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view",&ksp->viewer,&ksp->format,&ksp->view);
538: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pre",&ksp->viewerPre,&ksp->formatPre,&ksp->viewPre);
540: flg = PETSC_FALSE;
541: PetscOptionsBool("-ksp_converged_reason_view_cancel","Cancel all the converged reason view functions set using KSPConvergedReasonViewSet","KSPConvergedReasonViewCancel",PETSC_FALSE,&flg,&set);
542: if (set && flg) {
543: KSPConvergedReasonViewCancel(ksp);
544: }
545: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_converged_rate",&ksp->viewerRate,&ksp->formatRate,&ksp->viewRate);
546: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat",&ksp->viewerMat,&ksp->formatMat,&ksp->viewMat);
547: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_pmat",&ksp->viewerPMat,&ksp->formatPMat,&ksp->viewPMat);
548: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_rhs",&ksp->viewerRhs,&ksp->formatRhs,&ksp->viewRhs);
549: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_solution",&ksp->viewerSol,&ksp->formatSol,&ksp->viewSol);
550: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_mat_explicit",&ksp->viewerMatExp,&ksp->formatMatExp,&ksp->viewMatExp);
551: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
552: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
553: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_eigenvalues_explicit",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
554: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
555: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_preconditioned_operator_explicit",&ksp->viewerPOpExp,&ksp->formatPOpExp,&ksp->viewPOpExp);
556: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_view_diagonal_scale",&ksp->viewerDScale,&ksp->formatDScale,&ksp->viewDScale);
558: /* Deprecated options */
559: if (!ksp->viewEV) {
560: PetscOptionsDeprecated("-ksp_compute_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues");
561: PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues",&ksp->viewerEV,&ksp->formatEV,&ksp->viewEV);
562: }
563: if (!ksp->viewEV) {
564: PetscOptionsDeprecated("-ksp_plot_eigenvalues",NULL,"3.9","Use -ksp_view_eigenvalues draw");
565: PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV);
566: if (ksp->viewEV) {
567: ksp->formatEV = PETSC_VIEWER_DEFAULT;
568: ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
569: PetscObjectReference((PetscObject) ksp->viewerEV);
570: }
571: }
572: if (!ksp->viewEV) {
573: PetscOptionsDeprecated("-ksp_plot_eigencontours",NULL,"3.9","Use -ksp_view_eigenvalues draw::draw_contour");
574: PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV);
575: if (ksp->viewEV) {
576: ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
577: ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
578: PetscObjectReference((PetscObject) ksp->viewerEV);
579: }
580: }
581: if (!ksp->viewEVExp) {
582: PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit");
583: PetscOptionsGetViewer(comm, ((PetscObject) ksp)->options,prefix, "-ksp_compute_eigenvalues_explicitly",&ksp->viewerEVExp,&ksp->formatEVExp,&ksp->viewEVExp);
584: }
585: if (!ksp->viewEVExp) {
586: PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly",NULL,"3.9","Use -ksp_view_eigenvalues_explicit draw");
587: PetscOptionsName("-ksp_plot_eigenvalues_explicitly","[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]","KSPView",&ksp->viewEVExp);
588: if (ksp->viewEVExp) {
589: ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
590: ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
591: PetscObjectReference((PetscObject) ksp->viewerEVExp);
592: }
593: }
594: if (!ksp->viewSV) {
595: PetscOptionsDeprecated("-ksp_compute_singularvalues",NULL,"3.9","Use -ksp_view_singularvalues");
596: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_compute_singularvalues",&ksp->viewerSV,&ksp->formatSV,&ksp->viewSV);
597: }
598: if (!ksp->viewFinalRes) {
599: PetscOptionsDeprecated("-ksp_final_residual",NULL,"3.9","Use -ksp_view_final_residual");
600: PetscOptionsGetViewer(comm,((PetscObject) ksp)->options,prefix,"-ksp_final_residual",&ksp->viewerFinalRes,&ksp->formatFinalRes,&ksp->viewFinalRes);
601: }
603: #if defined(PETSC_HAVE_SAWS)
604: /*
605: Publish convergence information using AMS
606: */
607: PetscOptionsBool("-ksp_monitor_saws","Publish KSP progress using SAWs","KSPMonitorSet",PETSC_FALSE,&flg,&set);
608: if (set && flg) {
609: void *ctx;
610: KSPMonitorSAWsCreate(ksp,&ctx);
611: KSPMonitorSet(ksp,KSPMonitorSAWs,ctx,KSPMonitorSAWsDestroy);
612: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
613: }
614: #endif
616: /* -----------------------------------------------------------------------*/
617: KSPSetUpNorms_Private(ksp,PETSC_FALSE,NULL,&pcside);
618: PetscOptionsEnum("-ksp_pc_side","KSP preconditioner side","KSPSetPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg);
619: if (flg) KSPSetPCSide(ksp,pcside);
621: if (ksp->viewSV || ksp->viewEV) {
622: KSPSetComputeSingularValues(ksp,PETSC_TRUE);
623: }
625: #if defined(PETSC_HAVE_SAWS)
626: {
627: PetscBool set;
628: flg = PETSC_FALSE;
629: PetscOptionsBool("-ksp_saws_block","Block for SAWs at end of KSPSolve","PetscObjectSAWsBlock",((PetscObject)ksp)->amspublishblock,&flg,&set);
630: if (set) {
631: PetscObjectSAWsSetBlock((PetscObject)ksp,flg);
632: }
633: }
634: #endif
636: nmax = ksp->nmax;
637: PetscOptionsDeprecated("-ksp_matsolve_block_size","-ksp_matsolve_batch_size","3.15",NULL);
638: PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg);
639: if (flg) {
640: KSPSetMatSolveBatchSize(ksp, nmax);
641: }
643: flg = PETSC_FALSE;
644: PetscOptionsBool("-ksp_use_explicittranspose","Explicitly transpose the system in KSPSolveTranspose","KSPSetUseExplicitTranspose",ksp->transpose.use_explicittranspose,&flg,&set);
645: if (set) {
646: KSPSetUseExplicitTranspose(ksp,flg);
647: }
649: if (ksp->ops->setfromoptions) {
650: (*ksp->ops->setfromoptions)(PetscOptionsObject,ksp);
651: }
652: skipoptions:
653: /* process any options handlers added with PetscObjectAddOptionsHandler() */
654: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)ksp);
655: PetscOptionsEnd();
656: ksp->setfromoptionscalled++;
657: return 0;
658: }
660: /*@
661: KSPResetFromOptions - Sets various KSP parameters from user options ONLY if the KSP was previously set from options
663: Collective on ksp
665: Input Parameter:
666: . ksp - the KSP context
668: Level: beginner
670: .seealso: KSPSetFromOptions(), KSPSetOptionsPrefix()
671: @*/
672: PetscErrorCode KSPResetFromOptions(KSP ksp)
673: {
674: if (ksp->setfromoptionscalled) KSPSetFromOptions(ksp);
675: return 0;
676: }