xref: /petsc/src/ksp/ksp/interface/itcreate.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
1 /*
2      The basic KSP routines, Create, View etc. are here.
3 */
4 #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
5 
6 /* Logging support */
7 PetscClassId  KSP_CLASSID;
8 PetscClassId  DMKSP_CLASSID;
9 PetscClassId  KSPGUESS_CLASSID;
10 PetscLogEvent KSP_GMRESOrthogonalization, KSP_SetUp, KSP_Solve, KSP_SolveTranspose, KSP_MatSolve, KSP_MatSolveTranspose;
11 
12 /*
13    Contains the list of registered KSP routines
14 */
15 PetscFunctionList KSPList              = NULL;
16 PetscBool         KSPRegisterAllCalled = PETSC_FALSE;
17 
18 /*
19    Contains the list of registered KSP monitors
20 */
21 PetscFunctionList KSPMonitorList              = NULL;
22 PetscFunctionList KSPMonitorCreateList        = NULL;
23 PetscFunctionList KSPMonitorDestroyList       = NULL;
24 PetscBool         KSPMonitorRegisterAllCalled = PETSC_FALSE;
25 
26 /*@
27   KSPLoad - Loads a `KSP` that has been stored in a `PETSCVIEWERBINARY`  with `KSPView()`.
28 
29   Collective
30 
31   Input Parameters:
32 + newdm  - the newly loaded `KSP`, this needs to have been created with `KSPCreate()` or
33            some related function before a call to `KSPLoad()`.
34 - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()`
35 
36   Level: intermediate
37 
38   Note:
39   The type is determined by the data in the file, any type set into the `KSP` before this call is ignored.
40 
41 .seealso: [](ch_ksp), `KSP`, `PetscViewerBinaryOpen()`, `KSPView()`, `MatLoad()`, `VecLoad()`
42 @*/
KSPLoad(KSP newdm,PetscViewer viewer)43 PetscErrorCode KSPLoad(KSP newdm, PetscViewer viewer)
44 {
45   PetscBool isbinary;
46   PetscInt  classid;
47   char      type[256];
48   PC        pc;
49 
50   PetscFunctionBegin;
51   PetscValidHeaderSpecific(newdm, KSP_CLASSID, 1);
52   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
53   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
54   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
55 
56   PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT));
57   PetscCheck(classid == KSP_FILE_CLASSID, PetscObjectComm((PetscObject)newdm), PETSC_ERR_ARG_WRONG, "Not KSP next in file");
58   PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR));
59   PetscCall(KSPSetType(newdm, type));
60   PetscTryTypeMethod(newdm, load, viewer);
61   PetscCall(KSPGetPC(newdm, &pc));
62   PetscCall(PCLoad(pc, viewer));
63   PetscFunctionReturn(PETSC_SUCCESS);
64 }
65 
66 #include <petscdraw.h>
67 #if defined(PETSC_HAVE_SAWS)
68   #include <petscviewersaws.h>
69 #endif
70 /*@
71   KSPView - Prints the various parameters currently set in the `KSP` object. For example, the convergence tolerances and `KSPType`.
72   Also views the `PC` and `Mat` contained by the `KSP` with `PCView()` and `MatView()`.
73 
74   Collective
75 
76   Input Parameters:
77 + ksp    - the Krylov space context
78 - viewer - visualization context
79 
80   Options Database Key:
81 . -ksp_view - print the `KSP` data structure at the end of each `KSPSolve()` call
82 
83   Level: beginner
84 
85   Notes:
86   The available visualization contexts include
87 +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
88 -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
89   output where only the first processor opens
90   the file.  All other processors send their
91   data to the first processor to print.
92 
93   The available formats include
94 +     `PETSC_VIEWER_DEFAULT` - standard output (default)
95 -     `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `PCBJACOBI` and `PCASM`
96 
97   The user can open an alternative visualization context with
98   `PetscViewerASCIIOpen()` - output to a specified file.
99 
100   Use `KSPViewFromOptions()` to allow the user to select many different `PetscViewerType` and formats from the options database.
101 
102   In the debugger you can do call `KSPView(ksp,0)` to display the `KSP`. (The same holds for any PETSc object viewer).
103 
104 .seealso: [](ch_ksp), `KSP`, `PetscViewer`, `PCView()`, `PetscViewerASCIIOpen()`, `KSPViewFromOptions()`
105 @*/
KSPView(KSP ksp,PetscViewer viewer)106 PetscErrorCode KSPView(KSP ksp, PetscViewer viewer)
107 {
108   PetscBool isascii, isbinary, isdraw, isstring;
109 #if defined(PETSC_HAVE_SAWS)
110   PetscBool issaws;
111 #endif
112 
113   PetscFunctionBegin;
114   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
115   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)ksp), &viewer));
116   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
117   PetscCheckSameComm(ksp, 1, viewer, 2);
118 
119   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
120   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
121   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
122   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
123 #if defined(PETSC_HAVE_SAWS)
124   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
125 #endif
126   if (isascii) {
127     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)ksp, viewer));
128     PetscCall(PetscViewerASCIIPushTab(viewer));
129     PetscTryTypeMethod(ksp, view, viewer);
130     PetscCall(PetscViewerASCIIPopTab(viewer));
131     if (ksp->guess_zero) {
132       PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum iterations=%" PetscInt_FMT ", initial guess is zero\n", ksp->max_it));
133     } else {
134       PetscCall(PetscViewerASCIIPrintf(viewer, "  maximum iterations=%" PetscInt_FMT ", nonzero initial guess\n", ksp->max_it));
135     }
136     if (ksp->min_it) PetscCall(PetscViewerASCIIPrintf(viewer, "  minimum iterations=%" PetscInt_FMT "\n", ksp->min_it));
137     if (ksp->guess_knoll) PetscCall(PetscViewerASCIIPrintf(viewer, "  using preconditioner applied to right-hand side for initial guess\n"));
138     PetscCall(PetscViewerASCIIPrintf(viewer, "  tolerances: relative=%g, absolute=%g, divergence=%g\n", (double)ksp->rtol, (double)ksp->abstol, (double)ksp->divtol));
139     if (ksp->pc_side == PC_RIGHT) {
140       PetscCall(PetscViewerASCIIPrintf(viewer, "  right preconditioning\n"));
141     } else if (ksp->pc_side == PC_SYMMETRIC) {
142       PetscCall(PetscViewerASCIIPrintf(viewer, "  symmetric preconditioning\n"));
143     } else {
144       PetscCall(PetscViewerASCIIPrintf(viewer, "  left preconditioning\n"));
145     }
146     if (ksp->guess) {
147       PetscCall(PetscViewerASCIIPushTab(viewer));
148       PetscCall(KSPGuessView(ksp->guess, viewer));
149       PetscCall(PetscViewerASCIIPopTab(viewer));
150     }
151     if (ksp->dscale) PetscCall(PetscViewerASCIIPrintf(viewer, "  diagonally scaled system\n"));
152     if (ksp->converged == KSPConvergedSkip || ksp->normtype == KSP_NORM_NONE) PetscCall(PetscViewerASCIIPrintf(viewer, "  not checking for convergence\n"));
153     else PetscCall(PetscViewerASCIIPrintf(viewer, "  using %s norm type for convergence test\n", KSPNormTypes[ksp->normtype]));
154   } else if (isbinary) {
155     PetscInt    classid = KSP_FILE_CLASSID;
156     MPI_Comm    comm;
157     PetscMPIInt rank;
158     char        type[256];
159 
160     PetscCall(PetscObjectGetComm((PetscObject)ksp, &comm));
161     PetscCallMPI(MPI_Comm_rank(comm, &rank));
162     if (rank == 0) {
163       PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT));
164       PetscCall(PetscStrncpy(type, ((PetscObject)ksp)->type_name, 256));
165       PetscCall(PetscViewerBinaryWrite(viewer, type, 256, PETSC_CHAR));
166     }
167     PetscTryTypeMethod(ksp, view, viewer);
168   } else if (isstring) {
169     const char *type;
170     PetscCall(KSPGetType(ksp, &type));
171     PetscCall(PetscViewerStringSPrintf(viewer, " KSPType: %-7.7s", type));
172     PetscTryTypeMethod(ksp, view, viewer);
173   } else if (isdraw) {
174     PetscDraw draw;
175     char      str[36];
176     PetscReal x, y, bottom, h;
177     PetscBool flg;
178 
179     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
180     PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y));
181     PetscCall(PetscObjectTypeCompare((PetscObject)ksp, KSPPREONLY, &flg));
182     if (!flg) {
183       PetscCall(PetscStrncpy(str, "KSP: ", sizeof(str)));
184       PetscCall(PetscStrlcat(str, ((PetscObject)ksp)->type_name, sizeof(str)));
185       PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_RED, PETSC_DRAW_BLACK, str, NULL, &h));
186       bottom = y - h;
187     } else {
188       bottom = y;
189     }
190     PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom));
191 #if defined(PETSC_HAVE_SAWS)
192   } else if (issaws) {
193     PetscMPIInt rank;
194     const char *name;
195 
196     PetscCall(PetscObjectGetName((PetscObject)ksp, &name));
197     PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
198     if (!((PetscObject)ksp)->amsmem && rank == 0) {
199       char dir[1024];
200 
201       PetscCall(PetscObjectViewSAWs((PetscObject)ksp, viewer));
202       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name));
203       PetscCallSAWs(SAWs_Register, (dir, &ksp->its, 1, SAWs_READ, SAWs_INT));
204       if (!ksp->res_hist) PetscCall(KSPSetResidualHistory(ksp, NULL, PETSC_DECIDE, PETSC_TRUE));
205       PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/res_hist", name));
206       PetscCallSAWs(SAWs_Register, (dir, ksp->res_hist, 10, SAWs_READ, SAWs_DOUBLE));
207     }
208 #endif
209   } else PetscTryTypeMethod(ksp, view, viewer);
210   if (ksp->pc) PetscCall(PCView(ksp->pc, viewer));
211   if (isdraw) {
212     PetscDraw draw;
213     PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
214     PetscCall(PetscDrawPopCurrentPoint(draw));
215   }
216   PetscFunctionReturn(PETSC_SUCCESS);
217 }
218 
219 /*@
220   KSPViewFromOptions - View (print) a `KSP` object based on values in the options database. Also views the `PC` and `Mat` contained by the `KSP`
221   with `PCView()` and `MatView()`.
222 
223   Collective
224 
225   Input Parameters:
226 + A    - Krylov solver context
227 . obj  - Optional object that provides the options prefix used to query the options database
228 - name - command line option
229 
230   Level: intermediate
231 
232 .seealso: [](ch_ksp), `KSP`, `KSPView()`, `PetscObjectViewFromOptions()`, `KSPCreate()`
233 @*/
KSPViewFromOptions(KSP A,PetscObject obj,const char name[])234 PetscErrorCode KSPViewFromOptions(KSP A, PetscObject obj, const char name[])
235 {
236   PetscFunctionBegin;
237   PetscValidHeaderSpecific(A, KSP_CLASSID, 1);
238   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
239   PetscFunctionReturn(PETSC_SUCCESS);
240 }
241 
242 /*@
243   KSPSetNormType - Sets the type of residual norm that is used for convergence testing in `KSPSolve()` for the given `KSP` context
244 
245   Logically Collective
246 
247   Input Parameters:
248 + ksp      - Krylov solver context
249 - normtype - one of
250 .vb
251    KSP_NORM_NONE             - skips computing the norm, this should generally only be used if you are using
252                                the Krylov method as a smoother with a fixed small number of iterations.
253                                Implicitly sets `KSPConvergedSkip()` as the `KSP` convergence test.
254                                Note that certain algorithms such as `KSPGMRES` ALWAYS require the norm calculation,
255                                for these methods the norms are still computed, they are just not used in
256                                the convergence test.
257    KSP_NORM_PRECONDITIONED   - the default for left-preconditioned solves, uses the 2-norm
258                                of the preconditioned residual  $B^{-1}(b - A x)$.
259    KSP_NORM_UNPRECONDITIONED - uses the 2-norm of the true $b - Ax$ residual.
260    KSP_NORM_NATURAL          - uses the $A$ norm of the true $b - Ax$ residual; supported by `KSPCG`, `KSPCR`, `KSPCGNE`, `KSPCGS`
261 .ve
262 
263   Options Database Key:
264 . -ksp_norm_type <none,preconditioned,unpreconditioned,natural> - set `KSP` norm type
265 
266   Level: advanced
267 
268   Notes:
269   The norm is always of the equations residual $\| b - A x^n \|$  (or an approximation to that norm), they are never a norm of the error in the equation.
270 
271   Not all combinations of preconditioner side (see `KSPSetPCSide()`) and norm types are supported by all Krylov methods.
272   If only one is set, PETSc tries to automatically change the other to find a compatible pair.  If no such combination
273   is supported, PETSc will generate an error.
274 
275   Developer Note:
276   Supported combinations of norm and preconditioner side are set using `KSPSetSupportedNorm()` for each `KSPType`.
277 
278 .seealso: [](ch_ksp), `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetCheckNormIteration()`, `KSPSetPCSide()`, `KSPGetPCSide()`, `KSPNormType`
279 @*/
KSPSetNormType(KSP ksp,KSPNormType normtype)280 PetscErrorCode KSPSetNormType(KSP ksp, KSPNormType normtype)
281 {
282   PetscFunctionBegin;
283   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
284   PetscValidLogicalCollectiveEnum(ksp, normtype, 2);
285   ksp->normtype = ksp->normtype_set = normtype;
286   PetscFunctionReturn(PETSC_SUCCESS);
287 }
288 
289 /*@
290   KSPSetCheckNormIteration - Sets the first iteration at which the norm of the residual will be
291   computed and used in the convergence test of `KSPSolve()` for the given `KSP` context
292 
293   Logically Collective
294 
295   Input Parameters:
296 + ksp - Krylov solver context
297 - it  - use -1 to check at all iterations
298 
299   Level: advanced
300 
301   Notes:
302   Currently only works with `KSPCG`, `KSPBCGS` and `KSPIBCGS`
303 
304   Use `KSPSetNormType`(ksp,`KSP_NORM_NONE`) to never check the norm
305 
306   On steps where the norm is not computed, the previous norm is still in the variable, so if you run with, for example,
307   `-ksp_monitor` the residual norm will appear to be unchanged for several iterations (though it is not really unchanged).
308 
309   Certain methods such as `KSPGMRES` always compute the residual norm, this routine will not change that computation, but it will
310   prevent the computed norm from being checked.
311 
312 .seealso: [](ch_ksp), `KSP`, `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetNormType()`, `KSPSetLagNorm()`
313 @*/
KSPSetCheckNormIteration(KSP ksp,PetscInt it)314 PetscErrorCode KSPSetCheckNormIteration(KSP ksp, PetscInt it)
315 {
316   PetscFunctionBegin;
317   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
318   PetscValidLogicalCollectiveInt(ksp, it, 2);
319   ksp->chknorm = it;
320   PetscFunctionReturn(PETSC_SUCCESS);
321 }
322 
323 /*@
324   KSPSetLagNorm - Lags the residual norm calculation so that it is computed as part of the `MPI_Allreduce()` used for
325   computing the inner products needed for the next iteration.
326 
327   Logically Collective
328 
329   Input Parameters:
330 + ksp - Krylov solver context
331 - flg - `PETSC_TRUE` or `PETSC_FALSE`
332 
333   Options Database Key:
334 . -ksp_lag_norm - lag the calculated residual norm
335 
336   Level: advanced
337 
338   Notes:
339   Currently only works with `KSPIBCGS`.
340 
341   This can reduce communication costs at the expense of doing
342   one additional iteration because the norm used in the convergence test of `KSPSolve()` is one iteration behind the actual
343   current residual norm (which has not yet been computed due to the lag).
344 
345   Use `KSPSetNormType`(ksp,`KSP_NORM_NONE`) to never check the norm
346 
347   If you lag the norm and run with, for example, `-ksp_monitor`, the residual norm reported will be the lagged one.
348 
349   `KSPSetCheckNormIteration()` is an alternative way of avoiding the expense of computing the residual norm at each iteration.
350 
351 .seealso: [](ch_ksp), `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSPConvergedSkip()`, `KSPSetNormType()`, `KSPSetCheckNormIteration()`
352 @*/
KSPSetLagNorm(KSP ksp,PetscBool flg)353 PetscErrorCode KSPSetLagNorm(KSP ksp, PetscBool flg)
354 {
355   PetscFunctionBegin;
356   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
357   PetscValidLogicalCollectiveBool(ksp, flg, 2);
358   ksp->lagnorm = flg;
359   PetscFunctionReturn(PETSC_SUCCESS);
360 }
361 
362 /*@
363   KSPSetSupportedNorm - Sets a norm and preconditioner side supported by a `KSPType`
364 
365   Logically Collective
366 
367   Input Parameters:
368 + ksp      - Krylov method
369 . normtype - supported norm type of the type `KSPNormType`
370 . pcside   - preconditioner side, of the type `PCSide` that can be used with this `KSPNormType`
371 - priority - positive integer preference for this combination; larger values have higher priority
372 
373   Level: developer
374 
375   Notes:
376   This function should be called from the implementation files `KSPCreate_XXX()` to declare
377   which norms and preconditioner sides are supported. Users should not call this
378   function.
379 
380   This function can be called multiple times for each combination of `KSPNormType` and `PCSide`
381   the `KSPType` supports
382 
383 .seealso: [](ch_ksp), `KSP`, `KSPNormType`, `PCSide`, `KSPSetNormType()`, `KSPSetPCSide()`
384 @*/
KSPSetSupportedNorm(KSP ksp,KSPNormType normtype,PCSide pcside,PetscInt priority)385 PetscErrorCode KSPSetSupportedNorm(KSP ksp, KSPNormType normtype, PCSide pcside, PetscInt priority)
386 {
387   PetscFunctionBegin;
388   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
389   ksp->normsupporttable[normtype][pcside] = priority;
390   PetscFunctionReturn(PETSC_SUCCESS);
391 }
392 
KSPNormSupportTableReset_Private(KSP ksp)393 static PetscErrorCode KSPNormSupportTableReset_Private(KSP ksp)
394 {
395   PetscFunctionBegin;
396   PetscCall(PetscMemzero(ksp->normsupporttable, sizeof(ksp->normsupporttable)));
397   ksp->pc_side  = ksp->pc_side_set;
398   ksp->normtype = ksp->normtype_set;
399   PetscFunctionReturn(PETSC_SUCCESS);
400 }
401 
KSPSetUpNorms_Private(KSP ksp,PetscBool errorifnotsupported,KSPNormType * normtype,PCSide * pcside)402 PetscErrorCode KSPSetUpNorms_Private(KSP ksp, PetscBool errorifnotsupported, KSPNormType *normtype, PCSide *pcside)
403 {
404   PetscInt i, j, best, ibest = 0, jbest = 0;
405 
406   PetscFunctionBegin;
407   best = 0;
408   for (i = 0; i < KSP_NORM_MAX; i++) {
409     for (j = 0; j < PC_SIDE_MAX; j++) {
410       if ((ksp->normtype == KSP_NORM_DEFAULT || ksp->normtype == i) && (ksp->pc_side == PC_SIDE_DEFAULT || ksp->pc_side == j) && ksp->normsupporttable[i][j] > best) {
411         best  = ksp->normsupporttable[i][j];
412         ibest = i;
413         jbest = j;
414       }
415     }
416   }
417   if (best < 1 && errorifnotsupported) {
418     PetscCheck(ksp->normtype != KSP_NORM_DEFAULT || ksp->pc_side != PC_SIDE_DEFAULT, PetscObjectComm((PetscObject)ksp), PETSC_ERR_PLIB, "The %s KSP implementation did not call KSPSetSupportedNorm()", ((PetscObject)ksp)->type_name);
419     PetscCheck(ksp->normtype != KSP_NORM_DEFAULT, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "KSP %s does not support preconditioner side %s", ((PetscObject)ksp)->type_name, PCSides[ksp->pc_side]);
420     PetscCheck(ksp->pc_side != PC_SIDE_DEFAULT, PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "KSP %s does not support norm type %s", ((PetscObject)ksp)->type_name, KSPNormTypes[ksp->normtype]);
421     SETERRQ(PetscObjectComm((PetscObject)ksp), PETSC_ERR_SUP, "KSP %s does not support norm type %s with preconditioner side %s", ((PetscObject)ksp)->type_name, KSPNormTypes[ksp->normtype], PCSides[ksp->pc_side]);
422   }
423   if (normtype) *normtype = (KSPNormType)ibest;
424   if (pcside) *pcside = (PCSide)jbest;
425   PetscFunctionReturn(PETSC_SUCCESS);
426 }
427 
428 /*@
429   KSPGetNormType - Gets the `KSPNormType` that is used for convergence testing during `KSPSolve()` for this `KSP` context
430 
431   Not Collective
432 
433   Input Parameter:
434 . ksp - Krylov solver context
435 
436   Output Parameter:
437 . normtype - the `KSPNormType` that is used for convergence testing
438 
439   Level: advanced
440 
441 .seealso: [](ch_ksp), `KSPNormType`, `KSPSetNormType()`, `KSPConvergedSkip()`
442 @*/
KSPGetNormType(KSP ksp,KSPNormType * normtype)443 PetscErrorCode KSPGetNormType(KSP ksp, KSPNormType *normtype)
444 {
445   PetscFunctionBegin;
446   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
447   PetscAssertPointer(normtype, 2);
448   PetscCall(KSPSetUpNorms_Private(ksp, PETSC_TRUE, &ksp->normtype, &ksp->pc_side));
449   *normtype = ksp->normtype;
450   PetscFunctionReturn(PETSC_SUCCESS);
451 }
452 
453 #if defined(PETSC_HAVE_SAWS)
454   #include <petscviewersaws.h>
455 #endif
456 
457 /*@
458   KSPSetOperators - Sets the matrix associated with the linear system
459   and a (possibly) different one from which the preconditioner will be built into the `KSP` context. The matrix will then be used during `KSPSolve()`
460 
461   Collective
462 
463   Input Parameters:
464 + ksp  - the `KSP` context
465 . Amat - the matrix that defines the linear system
466 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`.
467 
468   Level: beginner
469 
470   Notes:
471 .vb
472   KSPSetOperators(ksp, Amat, Pmat);
473 .ve
474   is the same as
475 .vb
476   KSPGetPC(ksp, &pc);
477   PCSetOperators(pc, Amat, Pmat);
478 .ve
479   and is equivalent to
480 .vb
481   PCCreate(PetscObjectComm((PetscObject)ksp), &pc);
482   PCSetOperators(pc, Amat, Pmat);
483   KSPSetPC(ksp, pc);
484 .ve
485 
486   If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null
487   space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process.
488 
489   All future calls to `KSPSetOperators()` must use the same size matrices, unless `KSPReset()` is called!
490 
491   Passing a `NULL` for `Amat` or `Pmat` removes the matrix that is currently being used from the `KSP` context.
492 
493   If you wish to replace either `Amat` or `Pmat` but leave the other one untouched then
494   first call `KSPGetOperators()` to get the one you wish to keep, call `PetscObjectReference()`
495   on it and then pass it back in your call to `KSPSetOperators()`.
496 
497   Developer Notes:
498   If the operators have NOT been set with `KSPSetOperators()` then the operators
499   are created in the `PC` and returned to the user. In this case, if both operators
500   mat and pmat are requested, two DIFFERENT operators will be returned. If
501   only one is requested both operators in the `PC` will be the same (i.e. as
502   if one had called `KSPSetOperators()` with the same argument for both `Mat`s).
503   The user must set the sizes of the returned matrices and their type etc just
504   as if the user created them with `MatCreate()`. For example,
505 
506 .vb
507          KSPGetOperators(ksp/pc,&mat,NULL); is equivalent to
508            set size, type, etc of mat
509 
510          MatCreate(comm,&mat);
511          KSP/PCSetOperators(ksp/pc,mat,mat);
512          PetscObjectDereference((PetscObject)mat);
513            set size, type, etc of mat
514 
515      and
516 
517          KSP/PCGetOperators(ksp/pc,&mat,&pmat); is equivalent to
518            set size, type, etc of mat and pmat
519 
520          MatCreate(comm,&mat);
521          MatCreate(comm,&pmat);
522          KSP/PCSetOperators(ksp/pc,mat,pmat);
523          PetscObjectDereference((PetscObject)mat);
524          PetscObjectDereference((PetscObject)pmat);
525            set size, type, etc of mat and pmat
526 .ve
527 
528   The rationale for this support is so that when creating a `TS`, `SNES`, or `KSP` the hierarchy
529   of underlying objects (i.e. `SNES`, `KSP`, `PC`, `Mat`) and their lifespans can be completely
530   managed by the top most level object (i.e. the `TS`, `SNES`, or `KSP`). Another way to look
531   at this is when you create a `SNES` you do not NEED to create a `KSP` and attach it to
532   the `SNES` object (the `SNES` object manages it for you). Similarly when you create a `KSP`
533   you do not need to attach a `PC` to it (the `KSP` object manages the `PC` object for you).
534   Thus, why should YOU have to create the `Mat` and attach it to the `SNES`/`KSP`/`PC`, when
535   it can be created for you?
536 
537 .seealso: [](ch_ksp), `KSP`, `Mat`, `KSPSolve()`, `KSPGetPC()`, `PCGetOperators()`, `PCSetOperators()`, `KSPGetOperators()`, `KSPSetComputeOperators()`, `KSPSetComputeInitialGuess()`, `KSPSetComputeRHS()`
538 @*/
KSPSetOperators(KSP ksp,Mat Amat,Mat Pmat)539 PetscErrorCode KSPSetOperators(KSP ksp, Mat Amat, Mat Pmat)
540 {
541   PetscFunctionBegin;
542   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
543   if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2);
544   if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3);
545   if (Amat) PetscCheckSameComm(ksp, 1, Amat, 2);
546   if (Pmat) PetscCheckSameComm(ksp, 1, Pmat, 3);
547   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
548   PetscCall(PCSetOperators(ksp->pc, Amat, Pmat));
549   if (ksp->setupstage == KSP_SETUP_NEWRHS) ksp->setupstage = KSP_SETUP_NEWMATRIX; /* so that next solve call will call PCSetUp() on new matrix */
550   PetscFunctionReturn(PETSC_SUCCESS);
551 }
552 
553 /*@
554   KSPGetOperators - Gets the matrix associated with the linear system
555   and a (possibly) different one used to construct the preconditioner from the `KSP` context
556 
557   Collective
558 
559   Input Parameter:
560 . ksp - the `KSP` context
561 
562   Output Parameters:
563 + Amat - the matrix that defines the linear system
564 - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`.
565 
566   Level: intermediate
567 
568   Notes:
569   If `KSPSetOperators()` has not been called then the `KSP` object will attempt to automatically create the matrix `Amat` and return it
570 
571   Use `KSPGetOperatorsSet()` to determine if matrices have been provided.
572 
573   DOES NOT increase the reference counts of the matrix, so you should NOT destroy them.
574 
575 .seealso: [](ch_ksp), `KSP`, `KSPSolve()`, `KSPGetPC()`, `PCSetOperators()`, `KSPSetOperators()`, `KSPGetOperatorsSet()`
576 @*/
KSPGetOperators(KSP ksp,Mat * Amat,Mat * Pmat)577 PetscErrorCode KSPGetOperators(KSP ksp, Mat *Amat, Mat *Pmat)
578 {
579   PetscFunctionBegin;
580   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
581   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
582   PetscCall(PCGetOperators(ksp->pc, Amat, Pmat));
583   PetscFunctionReturn(PETSC_SUCCESS);
584 }
585 
586 /*@
587   KSPGetOperatorsSet - Determines if the matrix associated with the linear system and
588   possibly a different one from which the preconditioner will be built have been set in the `KSP` with `KSPSetOperators()`
589 
590   Not Collective, though the results on all processes will be the same
591 
592   Input Parameter:
593 . ksp - the `KSP` context
594 
595   Output Parameters:
596 + mat  - the matrix associated with the linear system was set
597 - pmat - matrix from which the preconditioner will be built, usually the same as `mat` was set
598 
599   Level: intermediate
600 
601   Note:
602   This routine exists because if you call `KSPGetOperators()` on a `KSP` that does not yet have operators they are
603   automatically created in the call.
604 
605 .seealso: [](ch_ksp), `KSP`, `PCSetOperators()`, `KSPGetOperators()`, `KSPSetOperators()`, `PCGetOperators()`, `PCGetOperatorsSet()`
606 @*/
KSPGetOperatorsSet(KSP ksp,PetscBool * mat,PetscBool * pmat)607 PetscErrorCode KSPGetOperatorsSet(KSP ksp, PetscBool *mat, PetscBool *pmat)
608 {
609   PetscFunctionBegin;
610   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
611   if (!ksp->pc) PetscCall(KSPGetPC(ksp, &ksp->pc));
612   PetscCall(PCGetOperatorsSet(ksp->pc, mat, pmat));
613   PetscFunctionReturn(PETSC_SUCCESS);
614 }
615 
616 /*@C
617   KSPSetPreSolve - Sets a function that is called at the beginning of each `KSPSolve()`. Used in conjunction with `KSPSetPostSolve()`.
618 
619   Logically Collective
620 
621   Input Parameters:
622 + ksp      - the solver object
623 . presolve - the function to call before the solve, see` KSPPSolveFn`
624 - ctx      - an optional context needed by the function
625 
626   Level: developer
627 
628   Notes:
629   The function provided here `presolve` is used to modify the right hand side, and possibly the matrix, of the linear system to be solved.
630   The function provided with `KSPSetPostSolve()` then modifies the resulting solution of that linear system to obtain the correct solution
631   to the initial linear system.
632 
633   The functions `PCPreSolve()` and `PCPostSolve()` provide a similar functionality and are used, for example with `PCEISENSTAT`.
634 
635 .seealso: [](ch_ksp), `KSPPSolveFn`, `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPSetPostSolve()`, `PCEISENSTAT`, `PCPreSolve()`, `PCPostSolve()`
636 @*/
KSPSetPreSolve(KSP ksp,KSPPSolveFn * presolve,PetscCtx ctx)637 PetscErrorCode KSPSetPreSolve(KSP ksp, KSPPSolveFn *presolve, PetscCtx ctx)
638 {
639   PetscFunctionBegin;
640   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
641   ksp->presolve = presolve;
642   ksp->prectx   = ctx;
643   PetscFunctionReturn(PETSC_SUCCESS);
644 }
645 
646 /*@C
647   KSPSetPostSolve - Sets a function that is called at the end of each `KSPSolve()` (whether it converges or not). Used in conjunction with `KSPSetPreSolve()`.
648 
649   Logically Collective
650 
651   Input Parameters:
652 + ksp       - the solver object
653 . postsolve - the function to call after the solve, see` KSPPSolveFn`
654 - ctx       - an optional context needed by the function
655 
656   Level: developer
657 
658 .seealso: [](ch_ksp), `KSPPSolveFn`, `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPSetPreSolve()`, `PCEISENSTAT`
659 @*/
KSPSetPostSolve(KSP ksp,KSPPSolveFn * postsolve,PetscCtx ctx)660 PetscErrorCode KSPSetPostSolve(KSP ksp, KSPPSolveFn *postsolve, PetscCtx ctx)
661 {
662   PetscFunctionBegin;
663   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
664   ksp->postsolve = postsolve;
665   ksp->postctx   = ctx;
666   PetscFunctionReturn(PETSC_SUCCESS);
667 }
668 
669 /*@
670   KSPSetNestLevel - sets the amount of nesting the `KSP` has. That is the number of levels of `KSP` above this `KSP` in a linear solve.
671 
672   Collective
673 
674   Input Parameters:
675 + ksp   - the `KSP`
676 - level - the nest level
677 
678   Level: developer
679 
680   Note:
681   For example, the `KSP` in each block of a `KSPBJACOBI` has a level of 1, while the outer `KSP` has a level of 0.
682 
683 .seealso: [](ch_ksp), `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPGMRES`, `KSPType`, `KSPGetNestLevel()`, `PCSetKSPNestLevel()`, `PCGetKSPNestLevel()`
684 @*/
KSPSetNestLevel(KSP ksp,PetscInt level)685 PetscErrorCode KSPSetNestLevel(KSP ksp, PetscInt level)
686 {
687   PetscFunctionBegin;
688   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
689   PetscValidLogicalCollectiveInt(ksp, level, 2);
690   ksp->nestlevel = level;
691   PetscFunctionReturn(PETSC_SUCCESS);
692 }
693 
694 /*@
695   KSPGetNestLevel - gets the amount of nesting the `KSP` has
696 
697   Not Collective
698 
699   Input Parameter:
700 . ksp - the `KSP`
701 
702   Output Parameter:
703 . level - the nest level
704 
705   Level: developer
706 
707 .seealso: [](ch_ksp), `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPGMRES`, `KSPType`, `KSPSetNestLevel()`, `PCSetKSPNestLevel()`, `PCGetKSPNestLevel()`
708 @*/
KSPGetNestLevel(KSP ksp,PetscInt * level)709 PetscErrorCode KSPGetNestLevel(KSP ksp, PetscInt *level)
710 {
711   PetscFunctionBegin;
712   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
713   PetscAssertPointer(level, 2);
714   *level = ksp->nestlevel;
715   PetscFunctionReturn(PETSC_SUCCESS);
716 }
717 
718 /*@
719   KSPCreate - Creates the `KSP` context. This `KSP` context is used in PETSc to solve linear systems with `KSPSolve()`
720 
721   Collective
722 
723   Input Parameter:
724 . comm - MPI communicator
725 
726   Output Parameter:
727 . inksp - location to put the `KSP` context
728 
729   Level: beginner
730 
731   Note:
732   The default `KSPType` is `KSPGMRES` with a restart of 30, using modified Gram-Schmidt orthogonalization. The `KSPType` may be
733   changed with `KSPSetType()`
734 
735 .seealso: [](ch_ksp), `KSPSetUp()`, `KSPSolve()`, `KSPDestroy()`, `KSP`, `KSPGMRES`, `KSPType`, `KSPSetType()`
736 @*/
KSPCreate(MPI_Comm comm,KSP * inksp)737 PetscErrorCode KSPCreate(MPI_Comm comm, KSP *inksp)
738 {
739   KSP      ksp;
740   PetscCtx ctx;
741 
742   PetscFunctionBegin;
743   PetscAssertPointer(inksp, 2);
744   PetscCall(KSPInitializePackage());
745 
746   PetscCall(PetscHeaderCreate(ksp, KSP_CLASSID, "KSP", "Krylov Method", "KSP", comm, KSPDestroy, KSPView));
747   ksp->default_max_it = ksp->max_it = 10000;
748   ksp->pc_side = ksp->pc_side_set = PC_SIDE_DEFAULT;
749 
750   ksp->default_rtol = ksp->rtol = 1.e-5;
751   ksp->default_abstol = ksp->abstol = PetscDefined(USE_REAL_SINGLE) ? 1.e-25 : 1.e-50;
752   ksp->default_divtol = ksp->divtol = 1.e4;
753 
754   ksp->chknorm  = -1;
755   ksp->normtype = ksp->normtype_set = KSP_NORM_DEFAULT;
756   ksp->rnorm                        = 0.0;
757   ksp->its                          = 0;
758   ksp->guess_zero                   = PETSC_TRUE;
759   ksp->calc_sings                   = PETSC_FALSE;
760   ksp->res_hist                     = NULL;
761   ksp->res_hist_alloc               = NULL;
762   ksp->res_hist_len                 = 0;
763   ksp->res_hist_max                 = 0;
764   ksp->res_hist_reset               = PETSC_TRUE;
765   ksp->err_hist                     = NULL;
766   ksp->err_hist_alloc               = NULL;
767   ksp->err_hist_len                 = 0;
768   ksp->err_hist_max                 = 0;
769   ksp->err_hist_reset               = PETSC_TRUE;
770   ksp->numbermonitors               = 0;
771   ksp->numberreasonviews            = 0;
772   ksp->setfromoptionscalled         = 0;
773   ksp->nmax                         = PETSC_DECIDE;
774 
775   PetscCall(KSPConvergedDefaultCreate(&ctx));
776   PetscCall(KSPSetConvergenceTest(ksp, KSPConvergedDefault, ctx, KSPConvergedDefaultDestroy));
777   ksp->ops->buildsolution = KSPBuildSolutionDefault;
778   ksp->ops->buildresidual = KSPBuildResidualDefault;
779 
780   ksp->vec_sol    = NULL;
781   ksp->vec_rhs    = NULL;
782   ksp->pc         = NULL;
783   ksp->data       = NULL;
784   ksp->nwork      = 0;
785   ksp->work       = NULL;
786   ksp->reason     = KSP_CONVERGED_ITERATING;
787   ksp->setupstage = KSP_SETUP_NEW;
788 
789   PetscCall(KSPNormSupportTableReset_Private(ksp));
790 
791   *inksp = ksp;
792   PetscFunctionReturn(PETSC_SUCCESS);
793 }
794 
795 /*@
796   KSPSetType - Sets the algorithm/method to be used to solve the linear system with the given `KSP`
797 
798   Logically Collective
799 
800   Input Parameters:
801 + ksp  - the Krylov space context
802 - type - a known method
803 
804   Options Database Key:
805 . -ksp_type  <method> - Sets the method; see `KSPType` or use `-help` for a list  of available methods (for instance, cg or gmres)
806 
807   Level: intermediate
808 
809   Notes:
810   See `KSPType` for available methods (for instance, `KSPCG` or `KSPGMRES`).
811 
812   Normally, it is best to use the `KSPSetFromOptions()` command and
813   then set the `KSP` type from the options database rather than by using
814   this routine.  Using the options database provides the user with
815   maximum flexibility in evaluating the many different Krylov methods.
816   The `KSPSetType()` routine is provided for those situations where it
817   is necessary to set the iterative solver independently of the command
818   line or options database.  This might be the case, for example, when
819   the choice of iterative solver changes during the execution of the
820   program, and the user's application is taking responsibility for
821   choosing the appropriate method.  In other words, this routine is
822   not for beginners.
823 
824   Developer Note:
825   `KSPRegister()` is used to add Krylov types to `KSPList` from which they are accessed by `KSPSetType()`.
826 
827 .seealso: [](ch_ksp), `PCSetType()`, `KSPType`, `KSPRegister()`, `KSPCreate()`, `KSP`
828 @*/
KSPSetType(KSP ksp,KSPType type)829 PetscErrorCode KSPSetType(KSP ksp, KSPType type)
830 {
831   PetscBool match;
832   PetscErrorCode (*r)(KSP);
833 
834   PetscFunctionBegin;
835   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
836   PetscAssertPointer(type, 2);
837 
838   PetscCall(PetscObjectTypeCompare((PetscObject)ksp, type, &match));
839   if (match) PetscFunctionReturn(PETSC_SUCCESS);
840 
841   PetscCall(PetscFunctionListFind(KSPList, type, &r));
842   PetscCheck(r, PetscObjectComm((PetscObject)ksp), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested KSP type %s", type);
843   /* Destroy the previous private KSP context */
844   PetscTryTypeMethod(ksp, destroy);
845 
846   /* Reinitialize function pointers in KSPOps structure */
847   PetscCall(PetscMemzero(ksp->ops, sizeof(struct _KSPOps)));
848   ksp->ops->buildsolution = KSPBuildSolutionDefault;
849   ksp->ops->buildresidual = KSPBuildResidualDefault;
850   PetscCall(KSPNormSupportTableReset_Private(ksp));
851   ksp->converged_neg_curve = PETSC_FALSE; // restore default
852   ksp->setupnewmatrix      = PETSC_FALSE; // restore default (setup not called in case of new matrix)
853   /* Call the KSPCreate_XXX routine for this particular Krylov solver */
854   ksp->setupstage     = KSP_SETUP_NEW;
855   ksp->guess_not_read = PETSC_FALSE; // restore default
856   PetscCall((*r)(ksp));
857   PetscCall(PetscObjectChangeTypeName((PetscObject)ksp, type));
858   PetscFunctionReturn(PETSC_SUCCESS);
859 }
860 
861 /*@
862   KSPGetType - Gets the `KSP` type as a string from the `KSP` object.
863 
864   Not Collective
865 
866   Input Parameter:
867 . ksp - Krylov context
868 
869   Output Parameter:
870 . type - name of the `KSP` method
871 
872   Level: intermediate
873 
874 .seealso: [](ch_ksp), `KSPType`, `KSP`, `KSPSetType()`
875 @*/
KSPGetType(KSP ksp,KSPType * type)876 PetscErrorCode KSPGetType(KSP ksp, KSPType *type)
877 {
878   PetscFunctionBegin;
879   PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
880   PetscAssertPointer(type, 2);
881   *type = ((PetscObject)ksp)->type_name;
882   PetscFunctionReturn(PETSC_SUCCESS);
883 }
884 
885 /*@C
886   KSPRegister -  Adds a method, `KSPType`, to the Krylov subspace solver package.
887 
888   Not Collective, No Fortran Support
889 
890   Input Parameters:
891 + sname    - name of a new user-defined solver
892 - function - routine to create method
893 
894   Level: advanced
895 
896   Note:
897   `KSPRegister()` may be called multiple times to add several user-defined solvers.
898 
899   Example Usage:
900 .vb
901    KSPRegister("my_solver", MySolverCreate);
902 .ve
903 
904   Then, your solver can be chosen with the procedural interface via
905 .vb
906   KSPSetType(ksp, "my_solver")
907 .ve
908   or at runtime via the option `-ksp_type my_solver`
909 
910 .seealso: [](ch_ksp), `KSP`, `KSPType`, `KSPSetType`, `KSPRegisterAll()`
911 @*/
KSPRegister(const char sname[],PetscErrorCode (* function)(KSP))912 PetscErrorCode KSPRegister(const char sname[], PetscErrorCode (*function)(KSP))
913 {
914   PetscFunctionBegin;
915   PetscCall(KSPInitializePackage());
916   PetscCall(PetscFunctionListAdd(&KSPList, sname, function));
917   PetscFunctionReturn(PETSC_SUCCESS);
918 }
919 
KSPMonitorMakeKey_Internal(const char name[],PetscViewerType vtype,PetscViewerFormat format,char key[])920 PetscErrorCode KSPMonitorMakeKey_Internal(const char name[], PetscViewerType vtype, PetscViewerFormat format, char key[])
921 {
922   PetscFunctionBegin;
923   PetscCall(PetscStrncpy(key, name, PETSC_MAX_PATH_LEN));
924   PetscCall(PetscStrlcat(key, ":", PETSC_MAX_PATH_LEN));
925   PetscCall(PetscStrlcat(key, vtype, PETSC_MAX_PATH_LEN));
926   PetscCall(PetscStrlcat(key, ":", PETSC_MAX_PATH_LEN));
927   PetscCall(PetscStrlcat(key, PetscViewerFormats[format], PETSC_MAX_PATH_LEN));
928   PetscFunctionReturn(PETSC_SUCCESS);
929 }
930 
931 /*@C
932   KSPMonitorRegister -  Registers a Krylov subspace solver monitor routine that may be accessed with `KSPMonitorSetFromOptions()`
933 
934   Not Collective
935 
936   Input Parameters:
937 + name    - name of a new monitor type
938 . vtype   - A `PetscViewerType` for the output
939 . format  - A `PetscViewerFormat` for the output
940 . monitor - Monitor routine, see `KSPMonitorRegisterFn`
941 . create  - Creation routine, or `NULL`
942 - destroy - Destruction routine, or `NULL`
943 
944   Level: advanced
945 
946   Notes:
947   `KSPMonitorRegister()` may be called multiple times to add several user-defined monitors.
948 
949   The calling sequence for the given function matches the calling sequence used by `KSPMonitorFn` functions passed to `KSPMonitorSet()` with the additional
950   requirement that its final argument be a `PetscViewerAndFormat`.
951 
952   Example Usage:
953 .vb
954   KSPMonitorRegister("my_monitor", PETSCVIEWERASCII, PETSC_VIEWER_ASCII_INFO_DETAIL, MyMonitor, NULL, NULL);
955 .ve
956 
957   Then, your monitor can be chosen with the procedural interface via
958 .vb
959   KSPMonitorSetFromOptions(ksp, "-ksp_monitor_my_monitor", "my_monitor", NULL)
960 .ve
961   or at runtime via the option `-ksp_monitor_my_monitor`
962 
963 .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorRegisterAll()`, `KSPMonitorSetFromOptions()`
964 @*/
KSPMonitorRegister(const char name[],PetscViewerType vtype,PetscViewerFormat format,KSPMonitorRegisterFn * monitor,KSPMonitorRegisterCreateFn * create,KSPMonitorRegisterDestroyFn * destroy)965 PetscErrorCode KSPMonitorRegister(const char name[], PetscViewerType vtype, PetscViewerFormat format, KSPMonitorRegisterFn *monitor, KSPMonitorRegisterCreateFn *create, KSPMonitorRegisterDestroyFn *destroy)
966 {
967   char key[PETSC_MAX_PATH_LEN];
968 
969   PetscFunctionBegin;
970   PetscCall(KSPInitializePackage());
971   PetscCall(KSPMonitorMakeKey_Internal(name, vtype, format, key));
972   PetscCall(PetscFunctionListAdd(&KSPMonitorList, key, monitor));
973   if (create) PetscCall(PetscFunctionListAdd(&KSPMonitorCreateList, key, create));
974   if (destroy) PetscCall(PetscFunctionListAdd(&KSPMonitorDestroyList, key, destroy));
975   PetscFunctionReturn(PETSC_SUCCESS);
976 }
977