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(PetscCtxRt ctx)
     51: {
     52:   KSPMonitor_SAWs *mon = *(KSPMonitor_SAWs **)ctx;

     54:   PetscFunctionBegin;
     55:   PetscCall(PetscFree2(mon->eigr, mon->eigi));
     56:   PetscCall(PetscFree(*(void **)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, PetscCtx 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: }