xref: /petsc/src/ksp/ksp/interface/saws/kspsaws.c (revision 4e8208cbcbc709572b8abe32f33c78b69c819375)
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