xref: /petsc/src/dm/impls/network/networkmonitor.c (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
1 #include <petscdmnetwork.h> /*I  "petscdmnetwork.h"  I*/
2 #include <petscdraw.h>
3 
4 /*@
5   DMNetworkMonitorCreate - Creates a network monitor context
6 
7   Collective on MPI_Comm
8 
9   Input Parameters:
10 . network - network to monitor
11 
12   Output Parameters:
13 . Monitorptr - Location to put network monitor context
14 
15   Level: intermediate
16 
17 .seealso: DMNetworkMonitorDestroy(), DMNetworkMonitorAdd()
18 @*/
19 PetscErrorCode DMNetworkMonitorCreate(DM network,DMNetworkMonitor *monitorptr)
20 {
21   PetscErrorCode   ierr;
22   DMNetworkMonitor monitor;
23   MPI_Comm         comm;
24   PetscMPIInt      size;
25 
26   PetscFunctionBegin;
27   ierr = PetscObjectGetComm((PetscObject)network,&comm);CHKERRQ(ierr);
28   ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr);
29   if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Parallel DMNetworkMonitor is not supported yet");
30 
31   ierr = PetscMalloc1(1,&monitor);CHKERRQ(ierr);
32   monitor->comm      = comm;
33   monitor->network   = network;
34   monitor->firstnode = NULL;
35 
36   *monitorptr = monitor;
37   PetscFunctionReturn(0);
38 }
39 
40 /*@
41   DMNetworkMonitorDestroy - Destroys a network monitor and all associated viewers
42 
43   Collective on DMNetworkMonitor
44 
45   Input Parameters:
46 . monitor - monitor to destroy
47 
48   Level: intermediate
49 
50 .seealso: DMNetworkMonitorCreate, DMNetworkMonitorAdd
51 @*/
52 PetscErrorCode DMNetworkMonitorDestroy(DMNetworkMonitor *monitor)
53 {
54   PetscErrorCode ierr;
55 
56   PetscFunctionBegin;
57   while ((*monitor)->firstnode) {
58     ierr = DMNetworkMonitorPop(*monitor);CHKERRQ(ierr);
59   }
60 
61   ierr = PetscFree(*monitor);CHKERRQ(ierr);
62   PetscFunctionReturn(0);
63 }
64 
65 /*@
66   DMNetworkMonitorPop - Removes the most recently added viewer
67 
68   Collective on DMNetworkMonitor
69 
70   Input Parameters:
71 . monitor - the monitor
72 
73   Level: intermediate
74 
75 .seealso: DMNetworkMonitorCreate(), DMNetworkMonitorDestroy()
76 @*/
77 PetscErrorCode DMNetworkMonitorPop(DMNetworkMonitor monitor)
78 {
79   PetscErrorCode       ierr;
80   DMNetworkMonitorList node;
81 
82   PetscFunctionBegin;
83   if (monitor->firstnode) {
84     /* Update links */
85     node = monitor->firstnode;
86     monitor->firstnode = node->next;
87 
88     /* Free list node */
89     ierr = PetscViewerDestroy(&(node->viewer));CHKERRQ(ierr);
90     ierr = VecDestroy(&(node->v));CHKERRQ(ierr);
91     ierr = PetscFree(node);CHKERRQ(ierr);
92   }
93   PetscFunctionReturn(0);
94 }
95 
96 /*@C
97   DMNetworkMonitorAdd - Adds a new viewer to monitor
98 
99   Collective on DMNetworkMonitor
100 
101   Input Parameters:
102 + monitor - the monitor
103 . name - name of viewer
104 . element - vertex / edge number
105 . nodes - number of nodes
106 . start - variable starting offset
107 . blocksize - variable blocksize
108 . ymin - ymin for viewer
109 . ymax - ymax for viewer
110 - hold - determines if plot limits should be held
111 
112   Level: intermediate
113 
114   Notes:
115   This is written to be independent of the semantics associated to the variables
116   at a given network vertex / edge.
117 
118   Precisely, the parameters nodes, start and blocksize allow you to select a general
119   strided subarray of the variables to monitor.
120 
121 .seealso: DMNetworkMonitorCreate(), DMNetworkMonitorDestroy()
122 @*/
123 PetscErrorCode DMNetworkMonitorAdd(DMNetworkMonitor monitor,const char *name,PetscInt element,PetscInt nodes,PetscInt start,PetscInt blocksize,PetscReal ymin,PetscReal ymax,PetscBool hold)
124 {
125   PetscErrorCode       ierr;
126   PetscDrawLG          drawlg;
127   PetscDrawAxis        axis;
128   PetscMPIInt          rank, size;
129   DMNetworkMonitorList node;
130   char                 titleBuffer[64];
131   PetscInt             vStart,vEnd,eStart,eEnd;
132 
133   PetscFunctionBegin;
134   ierr = MPI_Comm_rank(monitor->comm, &rank);CHKERRQ(ierr);
135   ierr = MPI_Comm_size(monitor->comm, &size);CHKERRQ(ierr);
136 
137   ierr = DMNetworkGetVertexRange(monitor->network, &vStart, &vEnd);CHKERRQ(ierr);
138   ierr = DMNetworkGetEdgeRange(monitor->network, &eStart, &eEnd);CHKERRQ(ierr);
139 
140   /* Make window title */
141   if (vStart <= element && element < vEnd) {
142     ierr = PetscSNPrintf(titleBuffer, 64, "%s @ vertex %d [%d / %d]", name, element - vStart, rank, size-1);CHKERRQ(ierr);
143   } else if (eStart <= element && element < eEnd) {
144     ierr = PetscSNPrintf(titleBuffer, 64, "%s @ edge %d [%d / %d]", name, element - eStart, rank, size-1);CHKERRQ(ierr);
145   } else {
146     /* vertex / edge is not on local machine, so skip! */
147     PetscFunctionReturn(0);
148   }
149 
150   ierr = PetscMalloc1(1, &node);CHKERRQ(ierr);
151 
152   /* Setup viewer. */
153   ierr = PetscViewerDrawOpen(monitor->comm, NULL, titleBuffer, PETSC_DECIDE, PETSC_DECIDE, PETSC_DRAW_QUARTER_SIZE, PETSC_DRAW_QUARTER_SIZE, &(node->viewer));CHKERRQ(ierr);
154   ierr = PetscViewerPushFormat(node->viewer, PETSC_VIEWER_DRAW_LG);CHKERRQ(ierr);
155   ierr = PetscViewerDrawGetDrawLG(node->viewer, 0, &drawlg);CHKERRQ(ierr);
156   ierr = PetscDrawLGGetAxis(drawlg, &axis);CHKERRQ(ierr);
157   ierr = PetscDrawAxisSetLimits(axis, 0, nodes-1, ymin, ymax);CHKERRQ(ierr);
158   ierr = PetscDrawAxisSetHoldLimits(axis, hold);CHKERRQ(ierr);
159 
160   /* Setup vector storage for drawing. */
161   ierr = VecCreateSeq(PETSC_COMM_SELF, nodes, &(node->v));CHKERRQ(ierr);
162 
163   node->element   = element;
164   node->nodes     = nodes;
165   node->start     = start;
166   node->blocksize = blocksize;
167 
168   node->next         = monitor->firstnode;
169   monitor->firstnode = node;
170   PetscFunctionReturn(0);
171 }
172 
173 /*@
174   DMNetworkMonitorView - Monitor function for TSMonitorSet.
175 
176   Collectiveon DMNetworkMonitor
177 
178   Input Parameters:
179 + monitor - DMNetworkMonitor object
180 - x - TS solution vector
181 
182   Level: intermediate
183 
184 .seealso: DMNetworkMonitorCreate(), DMNetworkMonitorDestroy(), DMNetworkMonitorAdd()
185 @*/
186 PetscErrorCode DMNetworkMonitorView(DMNetworkMonitor monitor,Vec x)
187 {
188   PetscErrorCode      ierr;
189   PetscInt            varoffset,i,start;
190   const PetscScalar   *xx;
191   PetscScalar         *vv;
192   DMNetworkMonitorList node;
193 
194   PetscFunctionBegin;
195   ierr = VecGetArrayRead(x, &xx);CHKERRQ(ierr);
196   for (node = monitor->firstnode; node; node = node->next) {
197     ierr = DMNetworkGetVariableGlobalOffset(monitor->network, node->element, &varoffset);CHKERRQ(ierr);
198     ierr = VecGetArray(node->v, &vv);CHKERRQ(ierr);
199     start = varoffset + node->start;
200     for (i = 0; i < node->nodes; i++) {
201       vv[i] = xx[start+i*node->blocksize];
202     }
203     ierr = VecRestoreArray(node->v, &vv);CHKERRQ(ierr);
204     ierr = VecView(node->v, node->viewer);CHKERRQ(ierr);
205   }
206   ierr = VecRestoreArrayRead(x, &xx);CHKERRQ(ierr);
207   PetscFunctionReturn(0);
208 }
209