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