Actual source code: kspams.c
petsc-3.3-p7 2013-05-11
1: #include <petsc-private/kspimpl.h> /*I "petscksp.h" I*/
3: typedef struct {
4: PetscViewer viewer;
5: PetscInt neigs;
6: PetscReal *eigi;
7: PetscReal *eigr;
8: #ifdef PETSC_HAVE_AMS
9: AMS_Memory amem;
10: #endif
11: } KSPMonitor_AMS;
15: /*@C
16: KSPMonitorAMSCreate - create an AMS monitor context
18: Collective
20: Input Arguments:
21: + ksp - KSP to monitor
22: - amscommname - name of AMS communicator to use
24: Output Arguments:
25: . ctx - context for monitor
27: Level: developer
29: .seealso: KSPMonitorAMS(), KSPMonitorAMSDestroy()
30: @*/
31: PetscErrorCode KSPMonitorAMSCreate(KSP ksp,const char *amscommname,void **ctx)
32: {
34: KSPMonitor_AMS *mon;
37: PetscNewLog(ksp,KSPMonitor_AMS,&mon);
38: #ifdef PETSC_HAVE_AMS
39: PetscViewerAMSOpen(((PetscObject)ksp)->comm,amscommname,&mon->viewer);
40: mon->amem = -1;
41: #endif
42: *ctx = (void*)mon;
43: return(0);
44: }
48: /*@C
49: KSPMonitorAMSDestroy - destroy a monitor context created with KSPMonitorAMSCreate()
51: Collective
53: Input Arguments:
54: . ctx - monitor context
56: Level: developer
58: .seealso: KSPMonitorAMSCreate()
59: @*/
60: PetscErrorCode KSPMonitorAMSDestroy(void **ctx)
61: {
62: KSPMonitor_AMS *mon = (KSPMonitor_AMS*)*ctx;
66: #ifdef PETSC_HAVE_AMS
67: if (mon->amem != -1) {
68: AMS_Memory_destroy(mon->amem);
69: mon->amem = -1;
70: }
71: #endif
72: PetscViewerDestroy(&mon->viewer);
73: PetscFree(mon->eigr);
74: mon->eigi = PETSC_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: {
100: #if defined(PETSC_HAVE_AMS)
102: KSPMonitor_AMS *mon = (KSPMonitor_AMS*)ctx;
103: PetscViewer viewer = mon->viewer;
104: PetscReal emax,emin;;
105: AMS_Comm acomm;
110: KSPComputeExtremeSingularValues(ksp,&emax,&emin);
112: /* UnPublish */
113: if (mon->amem != -1) {AMS_Memory_destroy(mon->amem);}
114: mon->amem = -1;
116: PetscFree(mon->eigr);
117: PetscMalloc(2*n*sizeof(PetscReal),&mon->eigr);
118: mon->eigi = mon->eigr + n;
119: if (n) {KSPComputeEigenvalues(ksp,n,mon->eigr,mon->eigi,&mon->neigs);}
121: PetscViewerAMSGetAMSComm(viewer,&acomm);
122: AMS_Memory_create(acomm,"ksp_monitor_ams",&mon->amem);
123: AMS_Memory_take_access(mon->amem);
125: AMS_Memory_add_field(mon->amem,"rnorm",&ksp->rnorm,1,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
126: AMS_Memory_add_field(mon->amem,"neigs",&mon->neigs,1,AMS_INT,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
127: if (mon->neigs > 0) {
128: AMS_Memory_add_field(mon->amem,"eigr",&mon->eigr,mon->neigs,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
129: AMS_Memory_add_field(mon->amem,"eigi",&mon->eigr,mon->neigs,AMS_DOUBLE,AMS_READ,AMS_COMMON,AMS_REDUCT_UNDEF);
130: }
131: AMS_Memory_publish(mon->amem);
132: AMS_Memory_grant_access(mon->amem);
134: PetscInfo2(ksp,"KSP extreme singular values min=%G max=%G\n",emin,emax);
135: return(0);
136: #else
138: SETERRQ(((PetscObject)ksp)->comm,PETSC_ERR_SUP,"Missing package AMS");
139: return(0);
140: #endif
141: }