Actual source code: kspams.c

petsc-3.4.5 2014-06-29
  1: #include <petsc-private/kspimpl.h>  /*I "petscksp.h" I*/
  2: #include <petscviewerams.h>

  4: typedef struct {
  5:   PetscViewer viewer;
  6:   PetscInt    neigs;
  7:   PetscReal   *eigi;
  8:   PetscReal   *eigr;
  9:   AMS_Memory amem;
 10: } KSPMonitor_AMS;

 14: /*@C
 15:    KSPMonitorAMSCreate - create an AMS monitor context

 17:    Collective

 19:    Input Arguments:
 20: +  ksp - KSP to monitor
 21: -  amscommname - name of AMS communicator to use, if NULL uses default "PETSc" communicator

 23:    Output Arguments:
 24: .  ctx - context for monitor

 26:    Level: developer

 28: .seealso: KSPMonitorAMS(), KSPMonitorAMSDestroy()
 29: @*/
 30: PetscErrorCode KSPMonitorAMSCreate(KSP ksp,const char *amscommname,void **ctx)
 31: {
 33:   KSPMonitor_AMS *mon;

 36:   PetscNewLog(ksp,KSPMonitor_AMS,&mon);
 37:   if (!amscommname) {
 38:     mon->viewer = PETSC_VIEWER_AMS_(PetscObjectComm((PetscObject)ksp));
 39:     if (!mon->viewer) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_PLIB,"Cannot create AMS default communicator");
 40:   } else {
 41:     PetscViewerAMSOpen(PetscObjectComm((PetscObject)ksp),amscommname,&mon->viewer);
 42:   }
 43:   mon->amem = -1;
 44:   *ctx = (void*)mon;
 45:   return(0);
 46: }

 50: /*@C
 51:    KSPMonitorAMSDestroy - destroy a monitor context created with KSPMonitorAMSCreate()

 53:    Collective

 55:    Input Arguments:
 56: .  ctx - monitor context

 58:    Level: developer

 60: .seealso: KSPMonitorAMSCreate()
 61: @*/
 62: PetscErrorCode KSPMonitorAMSDestroy(void **ctx)
 63: {
 64:   KSPMonitor_AMS *mon = (KSPMonitor_AMS*)*ctx;

 68:   if (mon->amem != -1) {
 69:     PetscStackCallAMS(AMS_Memory_destroy,(mon->amem));
 70:     mon->amem = -1;
 71:   }
 72:   PetscViewerDestroy(&mon->viewer);
 73:   PetscFree(mon->eigr);
 74:   mon->eigi = NULL;
 75:   PetscFree(*ctx);
 76:   return(0);
 77: }

 81: /*@C
 82:    KSPMonitorAMS - monitor solution using AMS

 84:    Logically Collective on KSP

 86:    Input Parameters:
 87: +  ksp   - iterative context
 88: .  n     - iteration number
 89: .  rnorm - 2-norm (preconditioned) residual value (may be estimated).
 90: -  ctx -  PetscViewer of type AMS

 92:    Level: advanced

 94: .keywords: KSP, CG, monitor, AMS, singular values

 96: .seealso: KSPMonitorSingularValue(), KSPComputeExtremeSingularValues(), PetscViewerAMSOpen()
 97: @*/
 98: PetscErrorCode KSPMonitorAMS(KSP ksp,PetscInt n,PetscReal rnorm,void *ctx)
 99: {
101:   KSPMonitor_AMS *mon   = (KSPMonitor_AMS*)ctx;
102:   PetscViewer    viewer = mon->viewer;
103:   PetscReal      emax,emin;;
104:   AMS_Comm       acomm;

109:   KSPComputeExtremeSingularValues(ksp,&emax,&emin);

111:   /* UnPublish  */
112:   if (mon->amem != -1) PetscStackCallAMS(AMS_Memory_destroy,(mon->amem));
113:   mon->amem = -1;

115:   PetscFree(mon->eigr);
116:   PetscMalloc(2*n*sizeof(PetscReal),&mon->eigr);
117:   mon->eigi = mon->eigr + n;
118:   if (n) {KSPComputeEigenvalues(ksp,n,mon->eigr,mon->eigi,&mon->neigs);}

120:   PetscViewerAMSGetAMSComm(viewer,&acomm);
121:   PetscStackCallAMS(AMS_Memory_create,(acomm,"ksp_monitor_ams",&mon->amem));
122:   PetscStackCallAMS(AMS_Memory_take_access,(mon->amem));

124:   PetscStackCallAMS(AMS_Memory_add_field,(mon->amem,"rnorm",&ksp->rnorm,1,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
125:   PetscStackCallAMS(AMS_Memory_add_field,(mon->amem,"neigs",&mon->neigs,1,AMS_INT,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
126:   if (mon->neigs > 0) {
127:     PetscStackCallAMS(AMS_Memory_add_field,(mon->amem,"eigr",&mon->eigr,mon->neigs,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
128:     PetscStackCallAMS(AMS_Memory_add_field,(mon->amem,"eigi",&mon->eigr,mon->neigs,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF));
129:   }
130:   PetscStackCallAMS(AMS_Memory_publish,(mon->amem));
131:   PetscStackCallAMS(AMS_Memory_grant_access,(mon->amem));

133:   PetscInfo2(ksp,"KSP extreme singular values min=%G max=%G\n",emin,emax);
134:   return(0);
135: }