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: }