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