1 /*
2 Code for setting KSP options from the options database.
3 */
4
5 #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
6 #include <petscdraw.h>
7
8 /*@
9 KSPSetOptionsPrefix - Sets the prefix used for searching for all
10 `KSP` options in the database.
11
12 Logically Collective
13
14 Input Parameters:
15 + ksp - the Krylov context
16 - prefix - the prefix string to prepend to all `KSP` option requests
17
18 Level: intermediate
19
20 Notes:
21 A hyphen (-) must NOT be given at the beginning of the prefix name.
22 The first character of all runtime options is AUTOMATICALLY the
23 hyphen.
24
25 For example, to distinguish between the runtime options for two
26 different `KSP` contexts, one could call
27 .vb
28 KSPSetOptionsPrefix(ksp1,"sys1_")
29 KSPSetOptionsPrefix(ksp2,"sys2_")
30 .ve
31
32 This would enable use of different options for each system, such as
33 .vb
34 -sys1_ksp_type gmres -sys1_ksp_rtol 1.e-3
35 -sys2_ksp_type bcgs -sys2_ksp_rtol 1.e-4
36 .ve
37
38 .seealso: [](ch_ksp), `KSP`, `KSPAppendOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
39 @*/
KSPSetOptionsPrefix(KSP ksp,const char prefix[])40 PetscErrorCode KSPSetOptionsPrefix(KSP ksp, const char prefix[])
41 {
42 PetscBool ispcmpi;
43
44 PetscFunctionBegin;
45 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
46 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
47 PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCMPI, &ispcmpi));
48 if (ispcmpi) {
49 size_t len;
50 const char suffix[] = "mpi_linear_solver_server_";
51 char *newprefix;
52
53 PetscCall(PetscStrlen(prefix, &len));
54 PetscCall(PetscMalloc1(len + sizeof(suffix) + 1, &newprefix));
55 PetscCall(PetscStrncpy(newprefix, prefix, len + sizeof(suffix)));
56 PetscCall(PetscStrlcat(newprefix, suffix, len + sizeof(suffix)));
57 PetscCall(PCSetOptionsPrefix(ksp->pc, newprefix));
58 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp, newprefix));
59 PetscCall(PetscFree(newprefix));
60 } else {
61 PetscCall(PCSetOptionsPrefix(ksp->pc, prefix));
62 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp, prefix));
63 }
64 PetscFunctionReturn(PETSC_SUCCESS);
65 }
66
67 /*@
68 KSPAppendOptionsPrefix - Appends to the prefix used for searching for all
69 `KSP` options in the database.
70
71 Logically Collective
72
73 Input Parameters:
74 + ksp - the Krylov context
75 - prefix - the prefix string to prepend to all `KSP` option requests
76
77 Level: intermediate
78
79 Note:
80 A hyphen (-) must NOT be given at the beginning of the prefix name.
81 The first character of all runtime options is AUTOMATICALLY the hyphen.
82
83 .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPGetOptionsPrefix()`, `KSPSetFromOptions()`
84 @*/
KSPAppendOptionsPrefix(KSP ksp,const char prefix[])85 PetscErrorCode KSPAppendOptionsPrefix(KSP ksp, const char prefix[])
86 {
87 PetscFunctionBegin;
88 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
89 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
90 PetscCall(PCAppendOptionsPrefix(ksp->pc, prefix));
91 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)ksp, prefix));
92 PetscFunctionReturn(PETSC_SUCCESS);
93 }
94
95 /*@
96 KSPSetUseFischerGuess - Use the Paul Fischer algorithm or its variants to compute initial guesses for a set of solves with related right-hand sides
97
98 Logically Collective
99
100 Input Parameters:
101 + ksp - the Krylov context
102 . model - use model 1, model 2, model 3, or any other number to turn it off
103 - size - size of subspace used to generate initial guess
104
105 Options Database Key:
106 . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
107
108 Level: advanced
109
110 .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetGuess()`, `KSPGetGuess()`, `KSPGuess`
111 @*/
KSPSetUseFischerGuess(KSP ksp,PetscInt model,PetscInt size)112 PetscErrorCode KSPSetUseFischerGuess(KSP ksp, PetscInt model, PetscInt size)
113 {
114 KSPGuess guess;
115
116 PetscFunctionBegin;
117 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
118 PetscValidLogicalCollectiveInt(ksp, model, 2);
119 PetscValidLogicalCollectiveInt(ksp, size, 3);
120 PetscCall(KSPGetGuess(ksp, &guess));
121 PetscCall(KSPGuessSetType(guess, KSPGUESSFISCHER));
122 PetscCall(KSPGuessFischerSetModel(guess, model, size));
123 PetscFunctionReturn(PETSC_SUCCESS);
124 }
125
126 /*@
127 KSPSetGuess - Set the initial guess object `KSPGuess` to be used by the `KSP` object to generate initial guesses
128
129 Logically Collective
130
131 Input Parameters:
132 + ksp - the Krylov context
133 - guess - the object created with `KSPGuessCreate()`
134
135 Level: advanced
136
137 Notes:
138 this allows a single `KSP` to be used with several different initial guess generators (likely for different linear
139 solvers, see `KSPSetPC()`).
140
141 This increases the reference count of the guess object, you must destroy the object with `KSPGuessDestroy()`
142 before the end of the program.
143
144 .seealso: [](ch_ksp), `KSP`, `KSPGuess`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPGetGuess()`
145 @*/
KSPSetGuess(KSP ksp,KSPGuess guess)146 PetscErrorCode KSPSetGuess(KSP ksp, KSPGuess guess)
147 {
148 PetscFunctionBegin;
149 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
150 PetscValidHeaderSpecific(guess, KSPGUESS_CLASSID, 2);
151 PetscCall(PetscObjectReference((PetscObject)guess));
152 PetscCall(KSPGuessDestroy(&ksp->guess));
153 ksp->guess = guess;
154 ksp->guess->ksp = ksp;
155 PetscFunctionReturn(PETSC_SUCCESS);
156 }
157
158 /*@
159 KSPGetGuess - Gets the initial guess generator for the `KSP`.
160
161 Not Collective
162
163 Input Parameter:
164 . ksp - the Krylov context
165
166 Output Parameter:
167 . guess - the object
168
169 Level: developer
170
171 .seealso: [](ch_ksp), `KSPGuess`, `KSP`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`, `KSPSetUseFischerGuess()`, `KSPSetGuess()`
172 @*/
KSPGetGuess(KSP ksp,KSPGuess * guess)173 PetscErrorCode KSPGetGuess(KSP ksp, KSPGuess *guess)
174 {
175 PetscFunctionBegin;
176 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
177 PetscAssertPointer(guess, 2);
178 if (!ksp->guess) {
179 const char *prefix;
180
181 PetscCall(KSPGuessCreate(PetscObjectComm((PetscObject)ksp), &ksp->guess));
182 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
183 if (prefix) PetscCall(PetscObjectSetOptionsPrefix((PetscObject)ksp->guess, prefix));
184 ksp->guess->ksp = ksp;
185 }
186 *guess = ksp->guess;
187 PetscFunctionReturn(PETSC_SUCCESS);
188 }
189
190 /*@
191 KSPGetOptionsPrefix - Gets the prefix used for searching for all
192 `KSP` options in the database.
193
194 Not Collective
195
196 Input Parameter:
197 . ksp - the Krylov context
198
199 Output Parameter:
200 . prefix - pointer to the prefix string used is returned
201
202 Level: advanced
203
204 .seealso: [](ch_ksp), `KSP`, `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`, `KSPAppendOptionsPrefix()`
205 @*/
KSPGetOptionsPrefix(KSP ksp,const char * prefix[])206 PetscErrorCode KSPGetOptionsPrefix(KSP ksp, const char *prefix[])
207 {
208 PetscFunctionBegin;
209 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
210 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, prefix));
211 PetscFunctionReturn(PETSC_SUCCESS);
212 }
213
PetscViewerAndFormatCreate_Internal(PetscViewer viewer,PetscViewerFormat format,PetscCtx ctx,PetscViewerAndFormat ** vf)214 static PetscErrorCode PetscViewerAndFormatCreate_Internal(PetscViewer viewer, PetscViewerFormat format, PetscCtx ctx, PetscViewerAndFormat **vf)
215 {
216 PetscFunctionBegin;
217 PetscCall(PetscViewerAndFormatCreate(viewer, format, vf));
218 (*vf)->data = ctx;
219 PetscFunctionReturn(PETSC_SUCCESS);
220 }
221
222 /*@C
223 KSPMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user in the options database
224
225 Collective
226
227 Input Parameters:
228 + ksp - `KSP` object you wish to monitor
229 . opt - the command line option for this monitor
230 . name - the monitor type one is seeking
231 - ctx - An optional user context for the monitor, or `NULL`
232
233 Level: developer
234
235 .seealso: [](ch_ksp), `KSPMonitorRegister()`, `KSPMonitorSet()`, `PetscOptionsCreateViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`,
236 `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()`
237 `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`,
238 `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`,
239 `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`,
240 `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`,
241 `PetscOptionsFList()`, `PetscOptionsEList()`
242 @*/
KSPMonitorSetFromOptions(KSP ksp,const char opt[],const char name[],PetscCtx ctx)243 PetscErrorCode KSPMonitorSetFromOptions(KSP ksp, const char opt[], const char name[], PetscCtx ctx)
244 {
245 PetscErrorCode (*mfunc)(KSP, PetscInt, PetscReal, void *);
246 PetscErrorCode (*cfunc)(PetscViewer, PetscViewerFormat, void *, PetscViewerAndFormat **);
247 PetscErrorCode (*dfunc)(PetscViewerAndFormat **);
248 PetscViewerAndFormat *vf;
249 PetscViewer viewer;
250 PetscViewerFormat format;
251 PetscViewerType vtype;
252 char key[PETSC_MAX_PATH_LEN];
253 PetscBool all, flg;
254 const char *prefix = NULL;
255
256 PetscFunctionBegin;
257 PetscCall(PetscStrcmp(opt, "-all_ksp_monitor", &all));
258 if (!all) PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
259 PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)ksp), ((PetscObject)ksp)->options, prefix, opt, &viewer, &format, &flg));
260 if (!flg) PetscFunctionReturn(PETSC_SUCCESS);
261
262 PetscCall(PetscViewerGetType(viewer, &vtype));
263 PetscCall(KSPMonitorMakeKey_Internal(name, vtype, format, key));
264 PetscCall(PetscFunctionListFind(KSPMonitorList, key, &mfunc));
265 PetscCall(PetscFunctionListFind(KSPMonitorCreateList, key, &cfunc));
266 PetscCall(PetscFunctionListFind(KSPMonitorDestroyList, key, &dfunc));
267 if (!cfunc) cfunc = PetscViewerAndFormatCreate_Internal;
268 if (!dfunc) dfunc = PetscViewerAndFormatDestroy;
269
270 PetscCall((*cfunc)(viewer, format, ctx, &vf));
271 PetscCall(PetscViewerDestroy(&viewer));
272 PetscCall(KSPMonitorSet(ksp, mfunc, vf, (PetscCtxDestroyFn *)dfunc));
273 PetscFunctionReturn(PETSC_SUCCESS);
274 }
275
276 PETSC_INTERN PetscErrorCode KSPCheckPCMPI(KSP);
277
278 /*@
279 KSPSetFromOptions - Sets `KSP` options from the options database.
280 This routine must be called before `KSPSetUp()` if the user is to be
281 allowed to set the Krylov type.
282
283 Collective
284
285 Input Parameter:
286 . ksp - the Krylov space context
287
288 Options Database Keys:
289 + -ksp_rtol rtol - relative tolerance used in default determination of convergence, i.e.
290 if residual norm decreases by this factor than convergence is declared
291 . -ksp_atol abstol - absolute tolerance used in default convergence test, i.e. if residual
292 norm is less than this then convergence is declared
293 . -ksp_divtol tol - if residual norm increases by this factor than divergence is declared
294 . -ksp_max_it - maximum number of linear iterations
295 . -ksp_min_it - minimum number of linear iterations to use, defaults to zero
296
297 . -ksp_reuse_preconditioner <true,false> - reuse the previously computed preconditioner
298
299 . -ksp_converged_use_initial_residual_norm - see `KSPConvergedDefaultSetUIRNorm()`
300 . -ksp_converged_use_min_initial_residual_norm - see `KSPConvergedDefaultSetUMIRNorm()`
301 . -ksp_converged_maxits - see `KSPConvergedDefaultSetConvergedMaxits()`
302 . -ksp_norm_type <none,preconditioned,unpreconditioned,natural> - see `KSPSetNormType()`
303 . -ksp_check_norm_iteration it - do not compute residual norm until iteration number it (does compute at 0th iteration)
304 works only for `KSPBCGS`, `KSPIBCGS`, and `KSPCG`
305 . -ksp_lag_norm - compute the norm of the residual for the ith iteration on the i+1 iteration;
306 this means that one can use the norm of the residual for convergence test WITHOUT
307 an extra `MPI_Allreduce()` limiting global synchronizations.
308 This will require 1 more iteration of the solver than usual.
309 . -ksp_guess_type - Type of initial guess generator for repeated linear solves
310 . -ksp_fischer_guess <model,size> - uses the Fischer initial guess generator for repeated linear solves
311 . -ksp_constant_null_space - assume the operator (matrix) has the constant vector in its null space
312 . -ksp_test_null_space - tests the null space set with `MatSetNullSpace()` to see if it truly is a null space
313 . -ksp_knoll - compute initial guess by applying the preconditioner to the right-hand side
314 . -ksp_monitor_cancel - cancel all previous convergene monitor routines set
315 . -ksp_monitor - print residual norm at each iteration
316 . -ksp_monitor draw::draw_lg - plot residual norm at each iteration, see `KSPMonitorResidual()`
317 . -ksp_monitor_true_residual - print the true l2 residual norm at each iteration, see `KSPMonitorTrueResidual()`
318 . -all_ksp_monitor <optional filename> - print residual norm at each iteration for ALL KSP solves, regardless of their prefix. This is
319 useful for `PCFIELDSPLIT`, `PCMG`, etc that have inner solvers and
320 you wish to track the convergence of all the solvers
321 . -ksp_monitor_solution [ascii binary or draw][:filename][:format option] - plot solution at each iteration
322 . -ksp_monitor_singular_value - monitor extreme singular values at each iteration
323 . -ksp_converged_reason - view the convergence state at the end of the solve
324 . -ksp_use_explicittranspose - transpose the system explicitly in `KSPSolveTranspose()`
325 . -ksp_error_if_not_converged - stop the program as soon as an error is detected in a `KSPSolve()`, `KSP_DIVERGED_ITS`
326 is not treated as an error on inner solves
327 - -ksp_converged_rate - view the convergence rate at the end of the solve
328
329 Level: beginner
330
331 Note:
332 To see all options, run your program with the `-help` option or consult [](ch_ksp)
333
334 .seealso: [](ch_ksp), `KSP`, `KSPSetOptionsPrefix()`, `KSPResetFromOptions()`, `KSPSetUseFischerGuess()`
335 @*/
KSPSetFromOptions(KSP ksp)336 PetscErrorCode KSPSetFromOptions(KSP ksp)
337 {
338 const char *convtests[] = {"default", "skip", "lsqr"}, *prefix;
339 char type[256], guesstype[256], monfilename[PETSC_MAX_PATH_LEN];
340 PetscBool flg, flag, reuse, set;
341 PetscInt indx, model[2] = {0, 0}, nmax, max_it;
342 KSPNormType normtype;
343 PCSide pcside;
344 void *ctx;
345 MPI_Comm comm;
346 PetscReal rtol, abstol, divtol;
347
348 PetscFunctionBegin;
349 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
350
351 PetscCall(PetscObjectGetComm((PetscObject)ksp, &comm));
352 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)ksp, &prefix));
353
354 PetscCall(KSPRegisterAll());
355 PetscObjectOptionsBegin((PetscObject)ksp);
356 PetscCall(PetscOptionsFList("-ksp_type", "Krylov method", "KSPSetType", KSPList, (char *)(((PetscObject)ksp)->type_name ? ((PetscObject)ksp)->type_name : KSPGMRES), type, 256, &flg));
357 if (flg) PetscCall(KSPSetType(ksp, type));
358 /*
359 Set the type if it was never set.
360 */
361 if (!((PetscObject)ksp)->type_name) PetscCall(KSPSetType(ksp, KSPGMRES));
362
363 PetscCall(KSPResetViewers(ksp));
364
365 /* Cancels all monitors hardwired into code before call to KSPSetFromOptions() */
366 PetscCall(PetscOptionsBool("-ksp_monitor_cancel", "Remove any hardwired monitor routines", "KSPMonitorCancel", PETSC_FALSE, &flg, &set));
367 if (set && flg) PetscCall(KSPMonitorCancel(ksp));
368 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor", "preconditioned_residual", NULL));
369 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_short", "preconditioned_residual_short", NULL));
370 PetscCall(KSPMonitorSetFromOptions(ksp, "-all_ksp_monitor", "preconditioned_residual", NULL));
371 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_range", "preconditioned_residual_range", NULL));
372 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_true_residual", "true_residual", NULL));
373 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_max", "true_residual_max", NULL));
374 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_solution", "solution", NULL));
375 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_singular_value", "singular_value", ksp));
376 PetscCall(KSPMonitorSetFromOptions(ksp, "-ksp_monitor_error", "error", ksp));
377 PetscCall(PetscOptionsBool("-ksp_monitor_pause_final", "Pauses all draw monitors at the final iterate", "KSPMonitorPauseFinal_Internal", PETSC_FALSE, &ksp->pauseFinal, NULL));
378 PetscCall(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));
379 if (flg) PetscCall(KSPSetInitialGuessNonzero(ksp, flag));
380
381 PetscCall(PetscObjectTypeCompare((PetscObject)ksp, KSPPREONLY, &flg));
382 if (flg) {
383 PetscCall(KSPGetReusePreconditioner(ksp, &reuse));
384 PetscCall(PetscOptionsBool("-ksp_reuse_preconditioner", "Use initial preconditioner and don't ever compute a new one", "KSPReusePreconditioner", reuse, &reuse, NULL));
385 PetscCall(KSPSetReusePreconditioner(ksp, reuse));
386 PetscCall(PetscOptionsBool("-ksp_error_if_not_converged", "Generate error if solver does not converge", "KSPSetErrorIfNotConverged", ksp->errorifnotconverged, &ksp->errorifnotconverged, &set));
387 if (set) PetscCall(KSPSetErrorIfNotConverged(ksp, ksp->errorifnotconverged));
388 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view", &ksp->viewer, &ksp->format, &ksp->view));
389 PetscCall(PetscViewerDestroy(&ksp->convergedreasonviewer));
390 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, ((PetscObject)ksp)->prefix, "-ksp_converged_reason", &ksp->convergedreasonviewer, &ksp->convergedreasonformat, NULL));
391 flg = PETSC_FALSE;
392 PetscCall(PetscOptionsBool("-ksp_converged_reason_view_cancel", "Cancel all the converged reason view functions set using KSPConvergedReasonViewSet", "KSPConvergedReasonViewCancel", PETSC_FALSE, &flg, &set));
393 if (set && flg) PetscCall(KSPConvergedReasonViewCancel(ksp));
394 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat));
395 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat));
396 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs));
397 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol));
398 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp));
399 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes));
400 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp));
401 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale));
402
403 PetscCall(KSPGetDiagonalScale(ksp, &flag));
404 PetscCall(PetscOptionsBool("-ksp_diagonal_scale", "Diagonal scale matrix before building preconditioner", "KSPSetDiagonalScale", flag, &flag, &flg));
405 if (flg) PetscCall(KSPSetDiagonalScale(ksp, flag));
406 PetscCall(KSPGetDiagonalScaleFix(ksp, &flag));
407 PetscCall(PetscOptionsBool("-ksp_diagonal_scale_fix", "Fix diagonally scaled matrix after solve", "KSPSetDiagonalScaleFix", flag, &flag, &flg));
408 if (flg) PetscCall(KSPSetDiagonalScaleFix(ksp, flag));
409 nmax = ksp->nmax;
410 PetscCall(PetscOptionsDeprecated("-ksp_matsolve_block_size", "-ksp_matsolve_batch_size", "3.15", NULL));
411 PetscCall(PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg));
412 if (flg) PetscCall(KSPSetMatSolveBatchSize(ksp, nmax));
413 goto skipoptions;
414 }
415
416 rtol = ksp->rtol;
417 abstol = ksp->abstol;
418 divtol = ksp->divtol;
419 max_it = ksp->max_it;
420 PetscCall(PetscOptionsReal("-ksp_rtol", "Relative decrease in residual norm", "KSPSetTolerances", ksp->rtol, &rtol, NULL));
421 PetscCall(PetscOptionsReal("-ksp_atol", "Absolute value of residual norm", "KSPSetTolerances", ksp->abstol, &abstol, NULL));
422 PetscCall(PetscOptionsReal("-ksp_divtol", "Residual norm increase cause divergence", "KSPSetTolerances", ksp->divtol, &divtol, NULL));
423 PetscCall(PetscOptionsInt("-ksp_max_it", "Maximum number of iterations", "KSPSetTolerances", ksp->max_it, &max_it, &flg));
424 PetscCall(KSPSetTolerances(ksp, rtol, abstol, divtol, max_it));
425 PetscCall(PetscOptionsRangeInt("-ksp_min_it", "Minimum number of iterations", "KSPSetMinimumIterations", ksp->min_it, &ksp->min_it, NULL, 0, ksp->max_it));
426
427 PetscCall(PetscOptionsBool("-ksp_converged_use_initial_residual_norm", "Use initial residual norm for computing relative convergence", "KSPConvergedDefaultSetUIRNorm", PETSC_FALSE, &flag, &set));
428 if (set && flag) PetscCall(KSPConvergedDefaultSetUIRNorm(ksp));
429 PetscCall(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));
430 if (set && flag) PetscCall(KSPConvergedDefaultSetUMIRNorm(ksp));
431 PetscCall(PetscOptionsBool("-ksp_converged_maxits", "Declare convergence if the maximum number of iterations is reached", "KSPConvergedDefaultSetConvergedMaxits", PETSC_FALSE, &flag, &set));
432 if (set) PetscCall(KSPConvergedDefaultSetConvergedMaxits(ksp, flag));
433 PetscCall(KSPGetConvergedNegativeCurvature(ksp, &flag));
434 PetscCall(PetscOptionsBool("-ksp_converged_neg_curve", "Declare convergence if negative curvature is detected", "KSPConvergedNegativeCurvature", flag, &flag, &set));
435 if (set) PetscCall(KSPSetConvergedNegativeCurvature(ksp, flag));
436 PetscCall(KSPGetReusePreconditioner(ksp, &reuse));
437 PetscCall(PetscOptionsBool("-ksp_reuse_preconditioner", "Use initial preconditioner and don't ever compute a new one", "KSPReusePreconditioner", reuse, &reuse, NULL));
438 PetscCall(KSPSetReusePreconditioner(ksp, reuse));
439
440 PetscCall(PetscOptionsBool("-ksp_knoll", "Use preconditioner applied to b for initial guess", "KSPSetInitialGuessKnoll", ksp->guess_knoll, &ksp->guess_knoll, NULL));
441 PetscCall(PetscOptionsBool("-ksp_error_if_not_converged", "Generate error if solver does not converge", "KSPSetErrorIfNotConverged", ksp->errorifnotconverged, &ksp->errorifnotconverged, &set));
442 if (set) PetscCall(KSPSetErrorIfNotConverged(ksp, ksp->errorifnotconverged));
443 PetscCall(PetscOptionsFList("-ksp_guess_type", "Initial guess in Krylov method", NULL, KSPGuessList, NULL, guesstype, 256, &flg));
444 if (flg) {
445 PetscCall(KSPGetGuess(ksp, &ksp->guess));
446 PetscCall(KSPGuessSetType(ksp->guess, guesstype));
447 PetscCall(KSPGuessSetFromOptions(ksp->guess));
448 } else { /* old option for KSP */
449 nmax = 2;
450 PetscCall(PetscOptionsIntArray("-ksp_fischer_guess", "Use Paul Fischer's algorithm or its variants for initial guess", "KSPSetUseFischerGuess", model, &nmax, &flag));
451 if (flag) {
452 PetscCheck(nmax == 2, comm, PETSC_ERR_ARG_OUTOFRANGE, "Must pass in model,size as arguments");
453 PetscCall(KSPSetUseFischerGuess(ksp, model[0], model[1]));
454 }
455 }
456
457 PetscCall(PetscOptionsEList("-ksp_convergence_test", "Convergence test", "KSPSetConvergenceTest", convtests, 3, "default", &indx, &flg));
458 if (flg) {
459 switch (indx) {
460 case 0:
461 PetscCall(KSPConvergedDefaultCreate(&ctx));
462 PetscCall(KSPSetConvergenceTest(ksp, KSPConvergedDefault, ctx, KSPConvergedDefaultDestroy));
463 break;
464 case 1:
465 PetscCall(KSPSetConvergenceTest(ksp, KSPConvergedSkip, NULL, NULL));
466 break;
467 case 2:
468 PetscCall(KSPConvergedDefaultCreate(&ctx));
469 PetscCall(KSPSetConvergenceTest(ksp, KSPLSQRConvergedDefault, ctx, KSPConvergedDefaultDestroy));
470 break;
471 }
472 }
473
474 PetscCall(KSPSetUpNorms_Private(ksp, PETSC_FALSE, &normtype, NULL));
475 PetscCall(PetscOptionsEnum("-ksp_norm_type", "KSP Norm type", "KSPSetNormType", KSPNormTypes, (PetscEnum)normtype, (PetscEnum *)&normtype, &flg));
476 if (flg) PetscCall(KSPSetNormType(ksp, normtype));
477
478 PetscCall(PetscOptionsInt("-ksp_check_norm_iteration", "First iteration to compute residual norm", "KSPSetCheckNormIteration", ksp->chknorm, &ksp->chknorm, NULL));
479
480 PetscCall(PetscOptionsBool("-ksp_lag_norm", "Lag the calculation of the residual norm", "KSPSetLagNorm", ksp->lagnorm, &flag, &flg));
481 if (flg) PetscCall(KSPSetLagNorm(ksp, flag));
482
483 PetscCall(KSPGetDiagonalScale(ksp, &flag));
484 PetscCall(PetscOptionsBool("-ksp_diagonal_scale", "Diagonal scale matrix before building preconditioner", "KSPSetDiagonalScale", flag, &flag, &flg));
485 if (flg) PetscCall(KSPSetDiagonalScale(ksp, flag));
486 PetscCall(KSPGetDiagonalScaleFix(ksp, &flag));
487 PetscCall(PetscOptionsBool("-ksp_diagonal_scale_fix", "Fix diagonally scaled matrix after solve", "KSPSetDiagonalScaleFix", flag, &flag, &flg));
488 if (flg) PetscCall(KSPSetDiagonalScaleFix(ksp, flag));
489
490 PetscCall(PetscOptionsBool("-ksp_constant_null_space", "Add constant null space to Krylov solver matrix", "MatSetNullSpace", PETSC_FALSE, &flg, &set));
491 if (set && flg) {
492 MatNullSpace nsp;
493 Mat Amat = NULL;
494
495 PetscCall(MatNullSpaceCreate(comm, PETSC_TRUE, 0, NULL, &nsp));
496 if (ksp->pc) PetscCall(PCGetOperators(ksp->pc, &Amat, NULL));
497 PetscCheck(Amat, comm, PETSC_ERR_ARG_WRONGSTATE, "Cannot set nullspace, matrix has not yet been provided");
498 PetscCall(MatSetNullSpace(Amat, nsp));
499 PetscCall(MatNullSpaceDestroy(&nsp));
500 }
501
502 flg = PETSC_FALSE;
503 if (ksp->pc) {
504 PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCKSP, &flg));
505 if (!flg) PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCBJACOBI, &flg));
506 if (!flg) PetscCall(PetscObjectTypeCompare((PetscObject)ksp->pc, PCDEFLATION, &flg));
507 }
508
509 if (flg) {
510 /* Using dynamic tolerance in preconditioner */
511 PetscCall(PetscOptionsString("-sub_ksp_dynamic_tolerance", "Use dynamic tolerance for inner PC", "KSPMonitorDynamicTolerance", "stdout", monfilename, sizeof(monfilename), &flg));
512 if (flg) {
513 void *scale;
514 PetscReal coeff = 1.0;
515
516 PetscCall(KSPMonitorDynamicToleranceCreate(&scale));
517 PetscCall(PetscOptionsReal("-sub_ksp_dynamic_tolerance", "Coefficient of dynamic tolerance for inner PC", "KSPMonitorDynamicTolerance", coeff, &coeff, &flg));
518 if (flg) PetscCall(KSPMonitorDynamicToleranceSetCoefficient(scale, coeff));
519 PetscCall(KSPMonitorSet(ksp, KSPMonitorDynamicTolerance, scale, KSPMonitorDynamicToleranceDestroy));
520 }
521 }
522
523 /*
524 Calls Python function
525 */
526 PetscCall(PetscOptionsString("-ksp_monitor_python", "Use Python function", "KSPMonitorSet", NULL, monfilename, sizeof(monfilename), &flg));
527 if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)ksp, monfilename));
528 /*
529 Graphically plots preconditioned residual norm and range of residual element values
530 */
531 PetscCall(PetscOptionsBool("-ksp_monitor_lg_range", "Monitor graphically range of preconditioned residual norm", "KSPMonitorSet", PETSC_FALSE, &flg, &set));
532 if (set && flg) {
533 PetscViewer ctx;
534
535 PetscCall(PetscViewerDrawOpen(comm, NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx));
536 PetscCall(KSPMonitorSet(ksp, KSPMonitorLGRange, ctx, (PetscCtxDestroyFn *)PetscViewerDestroy));
537 }
538 /* TODO Do these show up in help? */
539 PetscCall(PetscOptionsHasName(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &flg));
540 if (flg) {
541 const char *RateTypes[] = {"default", "residual", "error", "PetscRateType", "RATE_", NULL};
542 PetscEnum rtype = (PetscEnum)1;
543
544 PetscCall(PetscOptionsGetEnum(((PetscObject)ksp)->options, prefix, "-ksp_converged_rate_type", RateTypes, &rtype, &flg));
545 if (rtype == (PetscEnum)0 || rtype == (PetscEnum)1) PetscCall(KSPSetResidualHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE));
546 if (rtype == (PetscEnum)0 || rtype == (PetscEnum)2) PetscCall(KSPSetErrorHistory(ksp, NULL, PETSC_DETERMINE, PETSC_TRUE));
547 }
548 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view", &ksp->viewer, &ksp->format, &ksp->view));
549 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pre", &ksp->viewerPre, &ksp->formatPre, &ksp->viewPre));
550
551 PetscCall(PetscViewerDestroy(&ksp->convergedreasonviewer));
552 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, ((PetscObject)ksp)->prefix, "-ksp_converged_reason", &ksp->convergedreasonviewer, &ksp->convergedreasonformat, NULL));
553 flg = PETSC_FALSE;
554 PetscCall(PetscOptionsBool("-ksp_converged_reason_view_cancel", "Cancel all the converged reason view functions set using KSPConvergedReasonViewSet", "KSPConvergedReasonViewCancel", PETSC_FALSE, &flg, &set));
555 if (set && flg) PetscCall(KSPConvergedReasonViewCancel(ksp));
556 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_converged_rate", &ksp->viewerRate, &ksp->formatRate, &ksp->viewRate));
557 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat", &ksp->viewerMat, &ksp->formatMat, &ksp->viewMat));
558 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_pmat", &ksp->viewerPMat, &ksp->formatPMat, &ksp->viewPMat));
559 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_rhs", &ksp->viewerRhs, &ksp->formatRhs, &ksp->viewRhs));
560 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_solution", &ksp->viewerSol, &ksp->formatSol, &ksp->viewSol));
561 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_mat_explicit", &ksp->viewerMatExp, &ksp->formatMatExp, &ksp->viewMatExp));
562 PetscCall(PetscOptionsDeprecated("-ksp_compute_eigenvalues", "-ksp_view_eigenvalues", "3.9", NULL));
563 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues", &ksp->viewerEV, &ksp->formatEV, &ksp->viewEV));
564 PetscCall(PetscOptionsDeprecated("-ksp_compute_singularvalues", "-ksp_view_singularvalues", "3.9", NULL));
565 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_singularvalues", &ksp->viewerSV, &ksp->formatSV, &ksp->viewSV));
566 PetscCall(PetscOptionsDeprecated("-ksp_compute_eigenvalues_explicitly", "-ksp_view_eigenvalues_explicit", "3.9", NULL));
567 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_eigenvalues_explicit", &ksp->viewerEVExp, &ksp->formatEVExp, &ksp->viewEVExp));
568 PetscCall(PetscOptionsDeprecated("-ksp_final_residual", "-ksp_view_final_residual", "3.9", NULL));
569 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_final_residual", &ksp->viewerFinalRes, &ksp->formatFinalRes, &ksp->viewFinalRes));
570 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_preconditioned_operator_explicit", &ksp->viewerPOpExp, &ksp->formatPOpExp, &ksp->viewPOpExp));
571 PetscCall(PetscOptionsCreateViewer(comm, ((PetscObject)ksp)->options, prefix, "-ksp_view_diagonal_scale", &ksp->viewerDScale, &ksp->formatDScale, &ksp->viewDScale));
572
573 /* Deprecated options */
574 if (!ksp->viewEV) {
575 /* Cannot remove the what otherwise would be redundant call to PetscOptionsName("-ksp_plot_eigenvalues",...) below because the argument handling is different */
576 PetscCall(PetscOptionsDeprecated("-ksp_plot_eigenvalues", NULL, "3.9", "Use -ksp_view_eigenvalues draw"));
577 PetscCall(PetscOptionsName("-ksp_plot_eigenvalues", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw]", "KSPView", &ksp->viewEV));
578 if (ksp->viewEV) {
579 ksp->formatEV = PETSC_VIEWER_DEFAULT;
580 ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
581 PetscCall(PetscObjectReference((PetscObject)ksp->viewerEV));
582 }
583 }
584 if (!ksp->viewEV) {
585 PetscCall(PetscOptionsDeprecated("-ksp_plot_eigenvalues_explicitly", NULL, "3.9", "Use -ksp_view_eigenvalues_explicit draw"));
586 /* Cannot remove the what otherwise would be redundant call to PetscOptionsName("-ksp_plot_eigencontours",...) below because the argument handling is different */
587 PetscCall(PetscOptionsName("-ksp_plot_eigencontours", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues draw::draw_contour]", "KSPView", &ksp->viewEV));
588 if (ksp->viewEV) {
589 ksp->formatEV = PETSC_VIEWER_DRAW_CONTOUR;
590 ksp->viewerEV = PETSC_VIEWER_DRAW_(comm);
591 PetscCall(PetscObjectReference((PetscObject)ksp->viewerEV));
592 }
593 }
594 if (!ksp->viewEVExp) {
595 /* Cannot remove the what otherwise would be redundant call to PetscOptionsName("-ksp_plot_eigencontours_explicitly",...) below because the argument handling is different */
596 PetscCall(PetscOptionsName("-ksp_plot_eigenvalues_explicitly", "[deprecated since PETSc 3.9; use -ksp_view_eigenvalues_explicit draw]", "KSPView", &ksp->viewEVExp));
597 if (ksp->viewEVExp) {
598 ksp->formatEVExp = PETSC_VIEWER_DEFAULT;
599 ksp->viewerEVExp = PETSC_VIEWER_DRAW_(comm);
600 PetscCall(PetscObjectReference((PetscObject)ksp->viewerEVExp));
601 }
602 }
603
604 #if defined(PETSC_HAVE_SAWS)
605 /*
606 Publish convergence information using AMS
607 */
608 PetscCall(PetscOptionsBool("-ksp_monitor_saws", "Publish KSP progress using SAWs", "KSPMonitorSet", PETSC_FALSE, &flg, &set));
609 if (set && flg) {
610 PetscCtx ctx;
611 PetscCall(KSPMonitorSAWsCreate(ksp, &ctx));
612 PetscCall(KSPMonitorSet(ksp, KSPMonitorSAWs, ctx, KSPMonitorSAWsDestroy));
613 PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));
614 }
615 #endif
616
617 PetscCall(KSPSetUpNorms_Private(ksp, PETSC_FALSE, NULL, &pcside));
618 PetscCall(PetscOptionsEnum("-ksp_pc_side", "KSP preconditioner side", "KSPSetPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg));
619 if (flg) PetscCall(KSPSetPCSide(ksp, pcside));
620
621 if (ksp->viewSV || ksp->viewEV) PetscCall(KSPSetComputeSingularValues(ksp, PETSC_TRUE));
622
623 #if defined(PETSC_HAVE_SAWS)
624 {
625 PetscBool set;
626 flg = PETSC_FALSE;
627 PetscCall(PetscOptionsBool("-ksp_saws_block", "Block for SAWs at end of KSPSolve", "PetscObjectSAWsBlock", ((PetscObject)ksp)->amspublishblock, &flg, &set));
628 if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)ksp, flg));
629 }
630 #endif
631
632 nmax = ksp->nmax;
633 PetscCall(PetscOptionsDeprecated("-ksp_matsolve_block_size", "-ksp_matsolve_batch_size", "3.15", NULL));
634 PetscCall(PetscOptionsInt("-ksp_matsolve_batch_size", "Maximum number of columns treated simultaneously", "KSPSetMatSolveBatchSize", nmax, &nmax, &flg));
635 if (flg) PetscCall(KSPSetMatSolveBatchSize(ksp, nmax));
636
637 flg = PETSC_FALSE;
638 PetscCall(PetscOptionsBool("-ksp_use_explicittranspose", "Explicitly transpose the system in KSPSolveTranspose", "KSPSetUseExplicitTranspose", ksp->transpose.use_explicittranspose, &flg, &set));
639 if (set) PetscCall(KSPSetUseExplicitTranspose(ksp, flg));
640
641 PetscTryTypeMethod(ksp, setfromoptions, PetscOptionsObject);
642 skipoptions:
643 /* process any options handlers added with PetscObjectAddOptionsHandler() */
644 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)ksp, PetscOptionsObject));
645 PetscOptionsEnd();
646 ksp->setfromoptionscalled++;
647
648 if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
649 if (!ksp->skippcsetfromoptions) PetscCall(PCSetFromOptions(ksp->pc));
650 PetscFunctionReturn(PETSC_SUCCESS);
651 }
652
653 /*@
654 KSPResetFromOptions - Sets `KSP` parameters from user options ONLY if the `KSP` was previously set from options
655
656 Collective
657
658 Input Parameter:
659 . ksp - the `KSP` context
660
661 Level: advanced
662
663 .seealso: [](ch_ksp), `KSPSetFromOptions()`, `KSPSetOptionsPrefix()`
664 @*/
KSPResetFromOptions(KSP ksp)665 PetscErrorCode KSPResetFromOptions(KSP ksp)
666 {
667 PetscFunctionBegin;
668 if (ksp->setfromoptionscalled) PetscCall(KSPSetFromOptions(ksp));
669 PetscFunctionReturn(PETSC_SUCCESS);
670 }
671