Actual source code: kspsaws.c
1: #include <petsc/private/kspimpl.h>
2: #include <petscviewersaws.h>
4: typedef struct {
5: PetscViewer viewer;
6: PetscInt neigs;
7: PetscReal *eigi;
8: PetscReal *eigr;
9: } KSPMonitor_SAWs;
11: /*@C
12: KSPMonitorSAWsCreate - create an SAWs monitor context for `KSP`
14: Collective
16: Input Parameter:
17: . ksp - `KSP` to monitor
19: Output Parameter:
20: . ctx - context for monitor
22: Level: developer
24: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWs()`, `KSPMonitorSAWsDestroy()`
25: @*/
26: PetscErrorCode KSPMonitorSAWsCreate(KSP ksp, void **ctx)
27: {
28: KSPMonitor_SAWs *mon;
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: }
38: /*@C
39: KSPMonitorSAWsDestroy - destroy a monitor context created with `KSPMonitorSAWsCreate()`
41: Collective
43: Input Parameter:
44: . ctx - monitor context
46: Level: developer
48: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWsCreate()`
49: @*/
50: PetscErrorCode KSPMonitorSAWsDestroy(void **ctx)
51: {
52: KSPMonitor_SAWs *mon = (KSPMonitor_SAWs *)*ctx;
54: PetscFunctionBegin;
55: PetscCall(PetscFree2(mon->eigr, mon->eigi));
56: PetscCall(PetscFree(*ctx));
57: PetscFunctionReturn(PETSC_SUCCESS);
58: }
60: /*@C
61: KSPMonitorSAWs - monitor `KSP` solution using SAWs
63: Logically Collective
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()`
71: Level: advanced
73: Note:
74: Create the ctx with `KSPMonitorSAWsCreate()` then call `KSPMonitorSet()` with the context, this function, and `KSPMonitorSAWsDestroy()`
76: .seealso: [](ch_ksp), `KSP`, `KSPMonitorSet()`, `KSPMonitorSAWsCreate()`, `KSPMonitorSAWsDestroy()`, `KSPMonitorSingularValue()`, `KSPComputeExtremeSingularValues()`, `PetscViewerSAWsOpen()`
77: @*/
78: PetscErrorCode KSPMonitorSAWs(KSP ksp, PetscInt n, PetscReal rnorm, void *ctx)
79: {
80: KSPMonitor_SAWs *mon = (KSPMonitor_SAWs *)ctx;
81: PetscReal emax, emin;
82: PetscMPIInt rank;
84: PetscFunctionBegin;
86: PetscCall(KSPComputeExtremeSingularValues(ksp, &emax, &emin));
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));
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");
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: }