1 2 #include <../src/sys/classes/draw/utils/lgimpl.h> /*I "petscdraw.h" I*/ 3 #include <petscviewer.h> 4 PetscClassId PETSC_DRAWLG_CLASSID = 0; 5 6 #undef __FUNCT__ 7 #define __FUNCT__ "PetscDrawLGGetAxis" 8 /*@ 9 PetscDrawLGGetAxis - Gets the axis context associated with a line graph. 10 This is useful if one wants to change some axis property, such as 11 labels, color, etc. The axis context should not be destroyed by the 12 application code. 13 14 Not Collective, if PetscDrawLG is parallel then PetscDrawAxis is parallel 15 16 Input Parameter: 17 . lg - the line graph context 18 19 Output Parameter: 20 . axis - the axis context 21 22 Level: advanced 23 24 @*/ 25 PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis) 26 { 27 PetscFunctionBegin; 28 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) { 29 *axis = 0; 30 PetscFunctionReturn(0); 31 } 32 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 33 PetscValidPointer(axis,2); 34 *axis = lg->axis; 35 PetscFunctionReturn(0); 36 } 37 38 #undef __FUNCT__ 39 #define __FUNCT__ "PetscDrawLGGetDraw" 40 /*@ 41 PetscDrawLGGetDraw - Gets the draw context associated with a line graph. 42 43 Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel 44 45 Input Parameter: 46 . lg - the line graph context 47 48 Output Parameter: 49 . draw - the draw context 50 51 Level: intermediate 52 53 @*/ 54 PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw) 55 { 56 PetscFunctionBegin; 57 PetscValidHeader(lg,1); 58 PetscValidPointer(draw,2); 59 if (((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) *draw = (PetscDraw)lg; 60 else { 61 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 62 *draw = lg->win; 63 } 64 PetscFunctionReturn(0); 65 } 66 67 68 #undef __FUNCT__ 69 #define __FUNCT__ "PetscDrawLGSPDraw" 70 /*@ 71 PetscDrawLGSPDraw - Redraws a line graph. 72 73 Not Collective,but ignored by all processors except processor 0 in PetscDrawLG 74 75 Input Parameter: 76 . lg - the line graph context 77 78 Level: intermediate 79 80 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw() 81 82 Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same 83 84 @*/ 85 PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin) 86 { 87 PetscDrawLG sp = (PetscDrawLG)spin; 88 PetscReal xmin,xmax,ymin,ymax; 89 PetscErrorCode ierr; 90 int i,j,dim,nopts,rank; 91 PetscDraw draw = lg->win; 92 93 PetscFunctionBegin; 94 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 95 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 96 PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2); 97 98 xmin = PetscMin(lg->xmin,sp->xmin); 99 ymin = PetscMin(lg->ymin,sp->ymin); 100 xmax = PetscMax(lg->xmax,sp->xmax); 101 ymax = PetscMax(lg->ymax,sp->ymax); 102 103 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 104 ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr); 105 ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr); 106 107 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr); 108 if (!rank) { 109 110 dim = lg->dim; 111 nopts = lg->nopts; 112 for (i=0; i<dim; i++) { 113 for (j=1; j<nopts; j++) { 114 ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_BLACK+i);CHKERRQ(ierr); 115 if (lg->use_dots) { 116 ierr = PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED,"x");CHKERRQ(ierr); 117 } 118 } 119 } 120 121 dim = sp->dim; 122 nopts = sp->nopts; 123 for (i=0; i<dim; i++) { 124 for (j=0; j<nopts; j++) { 125 ierr = PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");CHKERRQ(ierr); 126 } 127 } 128 } 129 ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr); 130 ierr = PetscDrawPause(lg->win);CHKERRQ(ierr); 131 PetscFunctionReturn(0); 132 } 133 134 135 #undef __FUNCT__ 136 #define __FUNCT__ "PetscDrawLGCreate" 137 /*@ 138 PetscDrawLGCreate - Creates a line graph data structure. 139 140 Collective over PetscDraw 141 142 Input Parameters: 143 + draw - the window where the graph will be made. 144 - dim - the number of curves which will be drawn 145 146 Output Parameters: 147 . outctx - the line graph context 148 149 Level: intermediate 150 151 Concepts: line graph^creating 152 153 .seealso: PetscDrawLGDestroy() 154 @*/ 155 PetscErrorCode PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outctx) 156 { 157 PetscErrorCode ierr; 158 PetscBool isnull; 159 PetscObject obj = (PetscObject)draw; 160 PetscDrawLG lg; 161 162 PetscFunctionBegin; 163 PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1); 164 PetscValidPointer(outctx,2); 165 ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr); 166 if (isnull) { 167 ierr = PetscDrawOpenNull(PetscObjectComm((PetscObject)obj),(PetscDraw*)outctx);CHKERRQ(ierr); 168 PetscFunctionReturn(0); 169 } 170 ierr = PetscHeaderCreate(lg,_p_PetscDrawLG,int,PETSC_DRAWLG_CLASSID,"PetscDrawLG","Line graph","Draw",PetscObjectComm((PetscObject)obj),PetscDrawLGDestroy,0);CHKERRQ(ierr); 171 172 lg->view = 0; 173 lg->destroy = 0; 174 lg->nopts = 0; 175 lg->win = draw; 176 lg->dim = dim; 177 lg->xmin = 1.e20; 178 lg->ymin = 1.e20; 179 lg->xmax = -1.e20; 180 lg->ymax = -1.e20; 181 182 ierr = PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&lg->x,dim*CHUNCKSIZE,PetscReal,&lg->y);CHKERRQ(ierr); 183 ierr = PetscLogObjectMemory(lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr); 184 185 lg->len = dim*CHUNCKSIZE; 186 lg->loc = 0; 187 lg->use_dots= PETSC_FALSE; 188 189 ierr = PetscDrawAxisCreate(draw,&lg->axis);CHKERRQ(ierr); 190 ierr = PetscLogObjectParent(lg,lg->axis);CHKERRQ(ierr); 191 192 *outctx = lg; 193 PetscFunctionReturn(0); 194 } 195 196 #undef __FUNCT__ 197 #define __FUNCT__ "PetscDrawLGSetColors" 198 /*@ 199 PetscDrawLGSetColors - Sets the color of each line graph drawn 200 201 Logically Collective over PetscDrawLG 202 203 Input Parameter: 204 + lg - the line graph context. 205 - colors - the colors 206 207 Level: intermediate 208 209 Concepts: line graph^setting number of lines 210 211 @*/ 212 PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg,const int *colors) 213 { 214 PetscErrorCode ierr; 215 216 PetscFunctionBegin; 217 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 218 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 219 ierr = PetscFree(lg->colors);CHKERRQ(ierr); 220 ierr = PetscMalloc(lg->dim*sizeof(int),&lg->colors);CHKERRQ(ierr); 221 ierr = PetscMemcpy(lg->colors,colors,lg->dim*sizeof(int));CHKERRQ(ierr); 222 PetscFunctionReturn(0); 223 } 224 225 #undef __FUNCT__ 226 #undef __FUNCT__ 227 #define __FUNCT__ "PetscDrawLGSetLegend" 228 /*@C 229 PetscDrawLGSetLegend - sets the names of each curve plotted 230 231 Logically Collective over PetscDrawLG 232 233 Input Parameter: 234 + lg - the line graph context. 235 - names - the names for each curve 236 237 Level: intermediate 238 239 Concepts: line graph^setting number of lines 240 241 @*/ 242 PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names) 243 { 244 PetscErrorCode ierr; 245 PetscInt i; 246 247 PetscFunctionBegin; 248 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 249 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 250 251 if (lg->legend) { 252 for (i=0; i<lg->dim; i++) { 253 ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr); 254 } 255 ierr = PetscFree(lg->legend);CHKERRQ(ierr); 256 } 257 if (names) { 258 ierr = PetscMalloc(lg->dim*sizeof(char**),&lg->legend);CHKERRQ(ierr); 259 for (i=0; i<lg->dim; i++) { 260 ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr); 261 } 262 } 263 PetscFunctionReturn(0); 264 } 265 266 #undef __FUNCT__ 267 #define __FUNCT__ "PetscDrawLGGetDimension" 268 /*@ 269 PetscDrawLGGetDimension - Change the number of lines that are to be drawn. 270 271 Logically Collective over PetscDrawLG 272 273 Input Parameter: 274 . lg - the line graph context. 275 276 Output Parameter: 277 . dim - the number of curves. 278 279 Level: intermediate 280 281 Concepts: line graph^setting number of lines 282 283 @*/ 284 PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim) 285 { 286 PetscFunctionBegin; 287 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 288 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 289 *dim = lg->dim; 290 PetscFunctionReturn(0); 291 } 292 293 #undef __FUNCT__ 294 #define __FUNCT__ "PetscDrawLGSetDimension" 295 /*@ 296 PetscDrawLGSetDimension - Change the number of lines that are to be drawn. 297 298 Logically Collective over PetscDrawLG 299 300 Input Parameter: 301 + lg - the line graph context. 302 - dim - the number of curves. 303 304 Level: intermediate 305 306 Concepts: line graph^setting number of lines 307 308 @*/ 309 PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim) 310 { 311 PetscErrorCode ierr; 312 PetscInt i; 313 314 PetscFunctionBegin; 315 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 316 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 317 PetscValidLogicalCollectiveInt(lg,dim,2); 318 if (lg->dim == dim) PetscFunctionReturn(0); 319 320 ierr = PetscFree2(lg->x,lg->y);CHKERRQ(ierr); 321 if (lg->legend) { 322 for (i=0; i<lg->dim; i++) { 323 ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr); 324 } 325 ierr = PetscFree(lg->legend);CHKERRQ(ierr); 326 } 327 ierr = PetscFree(lg->colors);CHKERRQ(ierr); 328 lg->dim = dim; 329 ierr = PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&lg->x,dim*CHUNCKSIZE,PetscReal,&lg->y);CHKERRQ(ierr); 330 ierr = PetscLogObjectMemory(lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr); 331 lg->len = dim*CHUNCKSIZE; 332 PetscFunctionReturn(0); 333 } 334 335 #undef __FUNCT__ 336 #define __FUNCT__ "PetscDrawLGReset" 337 /*@ 338 PetscDrawLGReset - Clears line graph to allow for reuse with new data. 339 340 Logically Collective over PetscDrawLG 341 342 Input Parameter: 343 . lg - the line graph context. 344 345 Level: intermediate 346 347 Concepts: line graph^restarting 348 349 @*/ 350 PetscErrorCode PetscDrawLGReset(PetscDrawLG lg) 351 { 352 PetscFunctionBegin; 353 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 354 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 355 lg->xmin = 1.e20; 356 lg->ymin = 1.e20; 357 lg->xmax = -1.e20; 358 lg->ymax = -1.e20; 359 lg->loc = 0; 360 lg->nopts = 0; 361 PetscFunctionReturn(0); 362 } 363 364 #undef __FUNCT__ 365 #define __FUNCT__ "PetscDrawLGDestroy" 366 /*@ 367 PetscDrawLGDestroy - Frees all space taken up by line graph data structure. 368 369 Collective over PetscDrawLG 370 371 Input Parameter: 372 . lg - the line graph context 373 374 Level: intermediate 375 376 .seealso: PetscDrawLGCreate() 377 @*/ 378 PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg) 379 { 380 PetscErrorCode ierr; 381 PetscInt i; 382 383 PetscFunctionBegin; 384 if (!*lg) PetscFunctionReturn(0); 385 if (((PetscObject)(*lg))->classid != PETSC_DRAW_CLASSID) PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1); 386 387 if (--((PetscObject)(*lg))->refct > 0) {*lg = 0; PetscFunctionReturn(0);} 388 if (((PetscObject)(*lg))->classid == PETSC_DRAW_CLASSID) { 389 ierr = PetscObjectDestroy((PetscObject*)lg);CHKERRQ(ierr); 390 PetscFunctionReturn(0); 391 } 392 if ((*lg)->legend) { 393 for (i=0; i<(*lg)->dim; i++) { 394 ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr); 395 } 396 ierr = PetscFree((*lg)->legend);CHKERRQ(ierr); 397 } 398 ierr = PetscFree((*lg)->colors);CHKERRQ(ierr); 399 ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr); 400 ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr); 401 ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr); 402 PetscFunctionReturn(0); 403 } 404 #undef __FUNCT__ 405 #define __FUNCT__ "PetscDrawLGIndicateDataPoints" 406 /*@ 407 PetscDrawLGIndicateDataPoints - Causes LG to draw a big dot for each data-point. 408 409 Not Collective, but ignored by all processors except processor 0 in PetscDrawLG 410 411 Input Parameters: 412 . lg - the linegraph context 413 414 Level: intermediate 415 416 Concepts: line graph^showing points 417 418 @*/ 419 PetscErrorCode PetscDrawLGIndicateDataPoints(PetscDrawLG lg) 420 { 421 PetscFunctionBegin; 422 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 423 424 lg->use_dots = PETSC_TRUE; 425 PetscFunctionReturn(0); 426 } 427 428 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 429 #include <X11/Xlib.h> 430 #include <X11/Xutil.h> 431 #include <setjmp.h> 432 static jmp_buf PetscXIOErrorJumpBuf; 433 static void PetscXIOHandler(Display *dpy) 434 { 435 longjmp(PetscXIOErrorJumpBuf, 1); 436 } 437 #endif 438 439 #undef __FUNCT__ 440 #define __FUNCT__ "PetscDrawLGDraw" 441 /*@ 442 PetscDrawLGDraw - Redraws a line graph. 443 444 Not Collective,but ignored by all processors except processor 0 in PetscDrawLG 445 446 Input Parameter: 447 . lg - the line graph context 448 449 Level: intermediate 450 451 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw() 452 453 @*/ 454 PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg) 455 { 456 PetscReal xmin=lg->xmin,xmax=lg->xmax,ymin=lg->ymin,ymax=lg->ymax; 457 PetscErrorCode ierr; 458 int i,j,dim = lg->dim,nopts = lg->nopts,rank,cl; 459 PetscDraw draw = lg->win; 460 PetscBool isnull; 461 462 PetscFunctionBegin; 463 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 464 PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1); 465 ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr); 466 if (isnull) PetscFunctionReturn(0); 467 468 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 469 if (!setjmp(PetscXIOErrorJumpBuf)) XSetIOErrorHandler((XIOErrorHandler)PetscXIOHandler); 470 else { 471 XSetIOErrorHandler(NULL); 472 ierr = PetscDrawSetType(draw,PETSC_DRAW_NULL);CHKERRQ(ierr); 473 PetscFunctionReturn(0); 474 } 475 #endif 476 477 ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr); 478 ierr = PetscDrawClear(draw);CHKERRQ(ierr); 479 ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr); 480 ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr); 481 482 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr); 483 if (!rank) { 484 485 for (i=0; i<dim; i++) { 486 for (j=1; j<nopts; j++) { 487 if (lg->colors) cl = lg->colors[i]; 488 else cl = PETSC_DRAW_BLACK+i; 489 ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr); 490 if (lg->use_dots) { 491 ierr = PetscDrawString(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl,"x");CHKERRQ(ierr); 492 } 493 } 494 } 495 } 496 if (lg->legend) { 497 PetscReal xl,yl,xr,yr,tw,th; 498 size_t len,mlen = 0; 499 int cl; 500 ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 501 ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr); 502 for (i=0; i<dim; i++) { 503 ierr = PetscStrlen(lg->legend[i],&len);CHKERRQ(ierr); 504 mlen = PetscMax(mlen,len); 505 } 506 ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - 2*tw,yr - 3*th,PETSC_DRAW_BLACK);CHKERRQ(ierr); 507 ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - 3*th,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr); 508 for (i=0; i<dim; i++) { 509 cl = (lg->colors ? lg->colors[i] : i + 1); 510 ierr = PetscDrawLine(draw,xr - (mlen + 6.7)*tw,yr - (4 + i)*th,xr - (mlen + 3.2)*tw,yr - (4 + i)*th,cl);CHKERRQ(ierr); 511 ierr = PetscDrawString(draw,xr - (mlen + 3)*tw,yr - (4.5 + i)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr); 512 } 513 ierr = PetscDrawLine(draw,xr - 2*tw,yr - 3*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr); 514 ierr = PetscDrawLine(draw,xr - (mlen + 8)*tw,yr - (4+lg->dim)*th,xr - 2*tw,yr - (4+lg->dim)*th,PETSC_DRAW_BLACK);CHKERRQ(ierr); 515 } 516 ierr = PetscDrawFlush(lg->win);CHKERRQ(ierr); 517 ierr = PetscDrawPause(lg->win);CHKERRQ(ierr); 518 #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_X) 519 XSetIOErrorHandler(NULL); 520 #endif 521 PetscFunctionReturn(0); 522 } 523 524 #undef __FUNCT__ 525 #define __FUNCT__ "PetscDrawLGView" 526 /*@ 527 PetscDrawLGView - Prints a line graph. 528 529 Not collective 530 531 Input Parameter: 532 . lg - the line graph context 533 534 Level: beginner 535 536 .keywords: draw, line, graph 537 @*/ 538 PetscErrorCode PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer) 539 { 540 PetscReal xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax; 541 PetscInt i, j, dim = lg->dim, nopts = lg->nopts; 542 PetscErrorCode ierr; 543 544 PetscFunctionBegin; 545 if (lg && ((PetscObject)lg)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0); 546 PetscValidHeaderSpecific(lg, PETSC_DRAWLG_CLASSID,1); 547 if (nopts < 1) PetscFunctionReturn(0); 548 if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0); 549 550 if (!viewer){ 551 ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr); 552 } 553 for (i = 0; i < dim; i++) { 554 ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr); 555 for (j = 0; j < nopts; j++) { 556 ierr = PetscViewerASCIIPrintf(viewer, " X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr); 557 } 558 } 559 PetscFunctionReturn(0); 560 } 561