1 #include <petsc/private/kspimpl.h> /*I "petscksp.h" I*/
2 #include <petscviewersaws.h>
3
4 typedef struct {
5 PetscViewer viewer;
6 PetscInt neigs;
7 PetscReal *eigi;
8 PetscReal *eigr;
9 } KSPMonitor_SAWs;
10
11 /*@C
12 KSPMonitorSAWsCreate - create an SAWs monitor context for `KSP`
13
14 Collective
15
16 Input Parameter:
17 . ksp - `KSP` to monitor
18
19 Output Parameter:
20 . ctx - context for monitor
21
22 Level: developer
23
24 .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWs()`, `KSPMonitorSAWsDestroy()`
25 @*/
KSPMonitorSAWsCreate(KSP ksp,void ** ctx)26 PetscErrorCode KSPMonitorSAWsCreate(KSP ksp, void **ctx)
27 {
28 KSPMonitor_SAWs *mon;
29
30 PetscFunctionBegin;
31 PetscCall(PetscNew(&mon));
32 mon->viewer = PETSC_VIEWER_SAWS_(PetscObjectComm((PetscObject)ksp));
33 PetscCheck(mon->viewer, PetscObjectComm((PetscObject)ksp), PETSC_ERR_PLIB, "Cannot create SAWs default viewer");
34 *ctx = (void *)mon;
35 PetscFunctionReturn(PETSC_SUCCESS);
36 }
37
38 /*@C
39 KSPMonitorSAWsDestroy - destroy a monitor context created with `KSPMonitorSAWsCreate()`
40
41 Collective
42
43 Input Parameter:
44 . ctx - monitor context
45
46 Level: developer
47
48 .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWsCreate()`
49 @*/
KSPMonitorSAWsDestroy(PetscCtxRt ctx)50 PetscErrorCode KSPMonitorSAWsDestroy(PetscCtxRt ctx)
51 {
52 KSPMonitor_SAWs *mon = *(KSPMonitor_SAWs **)ctx;
53
54 PetscFunctionBegin;
55 PetscCall(PetscFree2(mon->eigr, mon->eigi));
56 PetscCall(PetscFree(*(void **)ctx));
57 PetscFunctionReturn(PETSC_SUCCESS);
58 }
59
60 /*@C
61 KSPMonitorSAWs - monitor `KSP` solution using SAWs
62
63 Logically Collective
64
65 Input Parameters:
66 + ksp - iterative context
67 . n - iteration number
68 . rnorm - 2-norm (preconditioned) residual value (may be estimated).
69 - ctx - created with `KSPMonitorSAWsCreate()`
70
71 Level: advanced
72
73 Note:
74 Create the ctx with `KSPMonitorSAWsCreate()` then call `KSPMonitorSet()` with the context, this function, and `KSPMonitorSAWsDestroy()`
75
76 .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWsCreate()`, `KSPMonitorSAWsDestroy()`, `KSPMonitorSingularValue()`, `KSPComputeExtremeSingularValues()`, `PetscViewerSAWsOpen()`
77 @*/
KSPMonitorSAWs(KSP ksp,PetscInt n,PetscReal rnorm,PetscCtx ctx)78 PetscErrorCode KSPMonitorSAWs(KSP ksp, PetscInt n, PetscReal rnorm, PetscCtx ctx)
79 {
80 KSPMonitor_SAWs *mon = (KSPMonitor_SAWs *)ctx;
81 PetscReal emax, emin;
82 PetscMPIInt rank;
83
84 PetscFunctionBegin;
85 PetscValidHeaderSpecific(ksp, KSP_CLASSID, 1);
86 PetscCall(KSPComputeExtremeSingularValues(ksp, &emax, &emin));
87
88 PetscCall(PetscFree2(mon->eigr, mon->eigi));
89 PetscCall(PetscMalloc2(n, &mon->eigr, n, &mon->eigi));
90 if (n) {
91 PetscCall(KSPComputeEigenvalues(ksp, n, mon->eigr, mon->eigi, &mon->neigs));
92
93 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
94 if (rank == 0) {
95 SAWs_Delete("/PETSc/ksp_monitor_saws/eigr");
96 SAWs_Delete("/PETSc/ksp_monitor_saws/eigi");
97
98 PetscCallSAWs(SAWs_Register, ("/PETSc/ksp_monitor_saws/rnorm", &ksp->rnorm, 1, SAWs_READ, SAWs_DOUBLE));
99 PetscCallSAWs(SAWs_Register, ("/PETSc/ksp_monitor_saws/neigs", &mon->neigs, 1, SAWs_READ, SAWs_INT));
100 if (mon->neigs > 0) {
101 PetscCallSAWs(SAWs_Register, ("/PETSc/ksp_monitor_saws/eigr", mon->eigr, mon->neigs, SAWs_READ, SAWs_DOUBLE));
102 PetscCallSAWs(SAWs_Register, ("/PETSc/ksp_monitor_saws/eigi", mon->eigi, mon->neigs, SAWs_READ, SAWs_DOUBLE));
103 }
104 PetscCall(PetscInfo(ksp, "KSP extreme singular values min=%g max=%g\n", (double)emin, (double)emax));
105 PetscCall(PetscSAWsBlock());
106 }
107 }
108 PetscFunctionReturn(PETSC_SUCCESS);
109 }
110