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: /*@C
170:   DMNetworkMonitorView - A `DMNETWORK` specific monitor function for `TSMonitorSet()`

172:   Collective, No Fortran support

174:   Input Parameters:
175: + monitor - `DMNetworkMonitor` object
176: - x       - `TS` solution vector

178:   Level: intermediate

180: .seealso: `DM`, `DMNETWORK`, `DMNetworkMonitor`, `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: }