1 | /*************************************** 2 | $Header: /cvsroot/petscgraphics/tsview.c,v 1.43 2006/01/30 04:53:58 hazelsct Exp $ 3 | 4 | This program views the output of a time series saved using 5 | +latex+{\tt IlluMultiSave()}. 6 | +html+ <tt>IlluMultiSave()</tt>. 7 | It basically just switches between timesteps; future versions may be more 8 | interesting. The neat part of it is that it loads multiprocessor data and 9 | displays it on a single CPU. 10 | ***************************************/ 11 | 12 | static char help[] = "Displays the output of of a timestep series saved using IlluMultiSave().\n\ 13 | Usage:\n\ 14 | \n\ 15 | tsview <basename> [-no_transparency]\n\ 16 | \n\ 17 | Then interactively flip through the timesteps (h or ? lists commands).\n"; 18 | 19 | #define HELP_STRING "tsview commands:\n\ 20 | <enter> Display next timestep\n\ 21 | b Display previous timestep\n\ 22 | i increment Set the next timestep increment\n\ 23 | ### Jump to timestep ###\n\ 24 | t Toggle Geomview transparency (3-D only)\n\ 25 | v Change field displayed (3-D only)\n\ 26 | d Dump geomview to picture (3-D only), creates basename-f%d.ppm\n\ 27 | a Dump all timesteps to pictures (3-D only)\n\ 28 | p [v1 v2 ...] Set contour values for plotting or \"auto\" (3-D only)\n\ 29 | r Reloads entries in a directory\n\ 30 | s size Set maximum dimension of PETSc viewer windows (2-D only)\n\ 31 | cx, cy, cz Toggle xcut, ycut, zcut (cut last row/plane of periodic DA)\n\ 32 | gx30-90, y,z Set plot x range to 30-90, same for y and z\n\ 33 | h/? Print this information\n\ 34 | q/x Quit tsview\n" 35 | 36 | #include "illuminator.h" 37 | #include <sys/dir.h> /* For scandir(), alphasort, struct dirent */ 38 | #include <libgen.h> /* For dirname(), basename() */ 39 | #include <string.h> /* For strdup() */ 40 | #include <stdlib.h> /* Needed for readline stuff below */ 41 | #include <term.h> /* ncurses header for readline */ 42 | #include <readline/readline.h> /* For command line editing */ 43 | #include <readline/history.h> /* For command line history */ 44 | 45 | /* Build with -DDEBUG for debugging output */ 46 | #undef DPRINTF 47 | #ifdef DEBUG 48 | #define DPRINTF(fmt, args...) PetscPrintf (PETSC_COMM_WORLD, "%s: " fmt, __FUNCT__, args) 49 | #else 50 | #define DPRINTF(fmt, args...) 51 | #endif 52 | 53 | char *basefilename; 54 | 55 | 56 | #undef __FUNCT__ 57 | #define __FUNCT__ "myfilter" 58 | 59 | /*++++++++++++++++++++++++++++++++++++++ 60 | This function returns non-zero for "qualifying" file names which start with 61 | the stored files' basename and end with 62 | +latex+{\tt .cpu0000.meta}. 63 | +html+ <tt>.cpu0000.meta</tt>. 64 | It is used as the 65 | +latex+{\tt select()} function for {\tt scandir()} in {\tt main()}. 66 | +html+ <tt>select()</tt> function for <tt>scandir()</tt> in <tt>main()</tt>. 67 | 68 | int myfilter Returns non-zero for qualifying filenames. 69 | 70 | const struct dirent *direntry Directory entry with filename to test. 71 | ++++++++++++++++++++++++++++++++++++++*/ 72 | 73 | int myfilter (const struct dirent *direntry) 74 | { 75 | if ((!strncmp (direntry->d_name, basefilename, strlen(basefilename)))) 76 | return (!strncmp (direntry->d_name + strlen(direntry->d_name) - 13, 77 | ".cpu0000.meta", 13)); 78 | return 0; 79 | } 80 | 81 | 82 | /*+++++++++++++++++++++++++++++++++++++ 83 | 84 | Functions for reading the command line 85 | and avoiding reading empty lines 86 | 87 | Probably this function is not Petsc 88 | safe, but we'll see. 89 | 90 | +++++++++++++++++++++++++++++++++++++*/ 91 | 92 | /* A static variable for holding the line. */ 93 | static char *line_read = (char *)NULL; 94 | 95 | /* Read a string, and return a pointer to it. 96 | Returns NULL on EOF. */ 97 | 98 | 99 | 100 | char* rl_gets (char* message) 101 | { 102 | /* If the buffer has already been allocated, 103 | return the memory to the free pool. */ 104 | if (line_read) 105 | { 106 | free (line_read); 107 | line_read = (char *)NULL; 108 | } 109 | 110 | /* Get a line from the user. */ 111 | line_read = readline (message); 112 | 113 | /* If the line has any text in it, 114 | save it on the history. */ 115 | if (line_read && *line_read) 116 | add_history (line_read); 117 | 118 | return (line_read); 119 | } 120 | 121 | 122 | /* 123 | Failed attempt to make a Petsc safe readline 124 | Lefted here for reference 125 | 126 | It is based on PetscSynchronizedFGets, but instead of using 127 | fgets() it uses rl_gets() 128 | 129 | */ 130 | 131 | int PetscSynchronizedFReadline(MPI_Comm comm,char* message,char* string) 132 | { 133 | int ierr,rank, len; 134 | PetscFunctionBegin; 135 | ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 136 | 137 | /* First processor prints immediately to stdin*/ 138 | if (!rank) { 139 | string = rl_gets(message); 140 | } 141 | 142 | len = strlen(string); 143 | 144 | ierr = MPI_Bcast(string,len,MPI_BYTE,0,comm);CHKERRQ(ierr); 145 | PetscFunctionReturn(0); 146 | } 147 | 148 | 149 | #undef __FUNCT__ 150 | #define __FUNCT__ "main" 151 | 152 | /*++++++++++++++++++++++++++++++++++++++ 153 | This is 154 | +latex+{\tt main()}. 155 | +html+ <tt>main()</tt>. 156 | 157 | int main It returns an int to the OS. 158 | 159 | int argc Argument count. 160 | 161 | char *argv[] Arguments. 162 | ++++++++++++++++++++++++++++++++++++++*/ 163 | 164 | int main (int argc, char *argv[]) 165 | { 166 | int total_entries, current_entry, dims, i, ierr, windowsize=300, plots=0, 167 | increment=1, xmin=0,xmax=-1, ymin=0,ymax=-1, zmin=0,zmax=-1; 168 | struct dirent **namelist; 169 | char **files, *thefilename, *filec, *dirc, *basedirname; 170 | PetscViewer theviewer; 171 | PetscTruth loaded = PETSC_FALSE, transp=PETSC_TRUE; 172 | 173 | if (argc<2) 174 | { 175 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Usage: tsview basename\n"); 176 | CHKERRQ (ierr); 177 | return 1; 178 | } 179 | 180 | /*+ After 181 | +latex+{\tt PETSc} 182 | +html+ <tt>PETSc</tt> 183 | initialization, it gets the list of files matching the basename. +*/ 184 | ierr = PetscInitialize (&argc, &argv, (char *)0, help); CHKERRQ (ierr); 185 | 186 | DPRINTF ("Command line:",0); CHKERRQ (ierr); 187 | #ifdef DEBUG 188 | for (i=0; i<argc; i++) 189 | { 190 | ierr = PetscPrintf (PETSC_COMM_WORLD, " %s", argv[i]); CHKERRQ (ierr); 191 | } 192 | ierr = PetscPrintf (PETSC_COMM_WORLD, "\n"); CHKERRQ (ierr); 193 | #endif 194 | 195 | filec = strdup (argv[1]); 196 | dirc = strdup (argv[1]); 197 | basefilename = basename (filec); 198 | basedirname = dirname (dirc); 199 | 200 | ierr = PetscOptionsHasName (PETSC_NULL, "-no_transparency", &transp); 201 | CHKERRQ (ierr); 202 | transp = !transp; 203 | 204 | total_entries = scandir (basedirname, &namelist, myfilter, alphasort); 205 | if (!total_entries) 206 | { 207 | ierr = PetscPrintf (PETSC_COMM_WORLD, "No such files, exiting\n"); 208 | CHKERRQ (ierr); 209 | exit (1); 210 | } 211 | if (total_entries < 0) 212 | { 213 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error scanning directory %s\n", 214 | basedirname); CHKERRQ (ierr); 215 | ierr = PetscFinalize (); CHKERRQ(ierr); 216 | return 1; 217 | } 218 | ierr = PetscPrintf (PETSC_COMM_WORLD, "%d eligible files:\n", total_entries); 219 | CHKERRQ (ierr); 220 | 221 | if (!(files = (char **) malloc (total_entries * sizeof (char *)))) 222 | { 223 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error allocating memory\n"); 224 | CHKERRQ (ierr); 225 | ierr = PetscFinalize (); CHKERRQ(ierr); 226 | return 1; 227 | } 228 | for (i=0; i<total_entries; i++) 229 | { 230 | int filength = strlen(namelist[i]->d_name); 231 | 232 | files [i] = (char *) malloc ((filength-12)*sizeof(char)); 233 | strncpy (files [i], namelist[i]->d_name, filength-13); 234 | files [i] [filength-13] = '\0'; 235 | free (namelist[i]); 236 | ierr = PetscPrintf (PETSC_COMM_WORLD, "[%d] %s\n", i, files [i]); 237 | CHKERRQ (ierr); 238 | } 239 | free (namelist); 240 | 241 | /*+In the main loop, the various timesteps are displayed, with options: 242 | +latex+\begin{itemize} \item 243 | +html+ <ul><li> 244 | A number jumps to that entry in the files table. 245 | +latex+\item {\stt <return>} 246 | +html+ <li><tt><return></tt> 247 | loads the next file. 248 | +latex+\item {\tt b} 249 | +html+ <li><tt>b</tt> 250 | goes back one file. 251 | +latex+\item {\tt q} 252 | +html+ <li><tt>q</tt> 253 | quits the program. 254 | +latex+\end{itemize} 255 | +html+ </ul> 256 | +*/ 257 | current_entry=0; 258 | while (1) 259 | { 260 | DA theda; 261 | Vec global; 262 | int usermetacount=0, fields, display_field; 263 | char basis [strlen(argv[1]) + 20], **usermetanames, **usermetadata, 264 | *instring; 265 | PetscScalar minmax[6], plot_vals[6], plot_colors[24] = 266 | { 1.,0.,0.,.5, 1.,1.,0.,.5, 0.,1.,0.,.5, 0.,1.,1.,.5, 0.,0.,1.,.5, 267 | 1.,0.,1.,.5 }; 268 | field_plot_type *fieldtypes; 269 | ISurface Surf; 270 | IDisplay Disp; 271 | 272 | /* Load the vector */ 273 | strcpy (basis, basedirname); 274 | strcat (basis, "/"); 275 | strcat (basis, files[current_entry]); 276 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Loading entry %d, basename %s\n", 277 | current_entry, basis); 278 | if (loaded) 279 | { 280 | ierr = IlluMultiRead (PETSC_COMM_WORLD, theda, global, basis, 281 | &usermetacount, &usermetanames, &usermetadata); 282 | CHKERRQ (ierr); 283 | } 284 | else 285 | { 286 | DPRINTF ("Loading first timestep, creating distributed array\n",0); 287 | display_field = 0; 288 | minmax [0] = minmax [2] = minmax [4] = 0.; 289 | minmax [1] = minmax [3] = minmax [5] = 1.; 290 | ierr = IlluMultiLoad 291 | (PETSC_COMM_WORLD, basis, &theda, minmax+1, minmax+3, minmax+5, 292 | &fieldtypes, &usermetacount, &usermetanames, &usermetadata); 293 | CHKERRQ (ierr); 294 | ierr = DAGetGlobalVector (theda, &global); CHKERRQ (ierr); 295 | loaded = PETSC_TRUE; 296 | 297 | ierr = DAGetInfo (theda, &dims, PETSC_NULL,PETSC_NULL,PETSC_NULL, 298 | PETSC_NULL,PETSC_NULL,PETSC_NULL, &fields, 299 | PETSC_NULL,PETSC_NULL,PETSC_NULL); CHKERRQ (ierr); 300 | 301 | /* Usermetadata xwidth, ywidth, zwidth override minmax in case 302 | version is 0.1. */ 303 | for (i=0; i<usermetacount; i++) 304 | { 305 | if (!strncmp (usermetanames [i], "xwidth", 6)) 306 | sscanf (usermetadata [i], "%lf", minmax+1); 307 | else if (!strncmp (usermetanames [i], "ywidth", 6)) 308 | sscanf (usermetadata [i], "%lf", minmax+3); 309 | else if (!strncmp (usermetanames [i], "zwidth", 6)) 310 | sscanf (usermetadata [i], "%lf", minmax+5); 311 | } 312 | 313 | if (dims<3) 314 | { 315 | int width=windowsize, height=windowsize; 316 | 317 | ierr = PetscPrintf (PETSC_COMM_WORLD, 318 | "For viewing 2-D data, try tsview-ng!\n"); 319 | CHKERRQ (ierr); 320 | 321 | if (minmax[1]<minmax[3]) 322 | width *= minmax[1]/minmax[3]; 323 | else 324 | height *= minmax[3]/minmax[1]; 325 | 326 | ierr = PetscViewerDrawOpen 327 | (PETSC_COMM_WORLD, 0, "", PETSC_DECIDE, PETSC_DECIDE, 328 | width, height, &theviewer); CHKERRQ (ierr); 329 | } 330 | else 331 | { 332 | #ifdef GEOMVIEW 333 | ierr = SurfCreate (&Surf); CHKERRQ (ierr); 334 | ierr = GeomviewBegin (PETSC_COMM_WORLD, &Disp); CHKERRQ (ierr); 335 | #else 336 | SETERRQ (PETSC_ERR_SUP, 337 | "Built without Geomview, which is needed for 3-D"); 338 | #endif 339 | } 340 | } 341 | 342 | /* Print user data */ 343 | ierr = PetscPrintf (PETSC_COMM_WORLD, "User data:\n"); CHKERRQ (ierr); 344 | for (i=0; i<usermetacount; i++) 345 | { 346 | ierr = PetscPrintf (PETSC_COMM_WORLD, "%s = %s\n", usermetanames [i], 347 | usermetadata [i]); CHKERRQ (ierr); 348 | } 349 | 350 | /* View the vector */ 351 | if (dims<3) 352 | { 353 | ierr = VecView (global, theviewer); CHKERRQ (ierr); 354 | } 355 | else 356 | { 357 | /*+ The Illuminator-based 3-D viewer can only display one field at a 358 | time. At the beginning, that is field 0, and is cycled using the 359 | +latex+{\tt v} 360 | +html+ <tt>v</tt> 361 | command. +*/ 362 | PetscScalar minval, maxval; 363 | char *fieldname; 364 | 365 | ierr = VecStrideMin (global, display_field, PETSC_NULL, &minval); 366 | CHKERRQ (ierr); 367 | ierr = VecStrideMax (global, display_field, PETSC_NULL, &maxval); 368 | CHKERRQ (ierr); 369 | ierr = DAGetFieldName (theda, display_field, &fieldname); 370 | CHKERRQ (ierr); 371 | ierr = PetscPrintf (PETSC_COMM_WORLD, 372 | "Displaying field %d [%g-%g]: %s\n", 373 | display_field, minval, maxval, fieldname); 374 | CHKERRQ (ierr); 375 | 376 | DPRINTF ("Calculating triangle locations\n",0); 377 | if (plots) 378 | { 379 | ierr = DATriangulateRange (Surf, theda, global, display_field, 380 | minmax, plots, plot_vals, plot_colors, 381 | xmin,xmax, ymin,ymax, zmin,zmax); 382 | CHKERRQ (ierr); 383 | } 384 | else 385 | { 386 | ierr = DATriangulateRange (Surf, theda, global, display_field, 387 | minmax, PETSC_DECIDE, PETSC_NULL, 388 | PETSC_NULL, xmin,xmax, ymin,ymax, 389 | zmin,zmax); 390 | CHKERRQ (ierr); 391 | } 392 | #ifdef GEOMVIEW 393 | DPRINTF ("Consolidating triangles on head node and visualizing\n",0); 394 | ierr = GeomviewDisplayTriangulation 395 | (PETSC_COMM_WORLD, Surf, Disp, minmax, fieldname, transp); 396 | CHKERRQ (ierr); 397 | #endif 398 | ierr = SurfClear (Surf); CHKERRQ (ierr); 399 | } 400 | 401 | /* Free user data */ 402 | for (i=0; i<usermetacount; i++) 403 | { 404 | free (usermetanames [i]); 405 | free (usermetadata [i]); 406 | } 407 | free (usermetanames); 408 | free (usermetadata); 409 | 410 | /* Get user input */ 411 | /* ierr = PetscPrintf (PETSC_COMM_WORLD, "What to do? (h for options) "); 412 | CHKERRQ (ierr); 413 | ierr = PetscSynchronizedFGets (PETSC_COMM_WORLD, stdin, 99, instring); 414 | CHKERRQ (ierr); */ 415 | /* This is probably not PETSc-safe */ 416 | instring = rl_gets("What to do? (h for options)> "); 417 | 418 | switch (instring [0]) 419 | { 420 | case 'q': 421 | case 'Q': 422 | case 'x': 423 | case 'X': 424 | { 425 | if (dims < 3) 426 | { 427 | ierr = PetscViewerDestroy (theviewer); CHKERRQ (ierr); 428 | } 429 | else 430 | { 431 | #ifdef GEOMVIEW 432 | ierr = GeomviewEnd (PETSC_COMM_WORLD, Disp); CHKERRQ (ierr); 433 | #endif 434 | ierr = ISurfDestroy (Surf); CHKERRQ (ierr); 435 | } 436 | ierr = PetscFinalize(); CHKERRQ (ierr); 437 | return 0; 438 | } 439 | case 't': 440 | case 'T': 441 | { 442 | transp=!transp; 443 | break; 444 | } 445 | case 'h': 446 | case 'H': 447 | case '?': 448 | { 449 | ierr = PetscPrintf (PETSC_COMM_WORLD, HELP_STRING); 450 | break; 451 | } 452 | case '0': 453 | case '1': 454 | case '2': 455 | case '3': 456 | case '4': 457 | case '5': 458 | case '6': 459 | case '7': 460 | case '8': 461 | case '9': 462 | { 463 | current_entry = atoi (instring); 464 | break; 465 | } 466 | case 'b': 467 | case 'B': 468 | { 469 | current_entry--; 470 | break; 471 | } 472 | case 'i': 473 | case 'I': 474 | { 475 | /* printf ("instring=\"%s\"\n",instring); */ 476 | if (instring[1] && instring[2]) 477 | { 478 | sscanf (instring, "i %d", &increment); 479 | } 480 | else 481 | { 482 | ierr=PetscPrintf (PETSC_COMM_WORLD, 483 | "Increment: %d\n",increment); 484 | CHKERRQ (ierr); 485 | } 486 | break; 487 | } 488 | case 'v': 489 | case 'V': 490 | { 491 | if (dims == 3) 492 | display_field = (display_field+1) % fields; 493 | break; 494 | } 495 | #ifdef GEOMVIEW 496 | case 'd': 497 | case 'D': 498 | { 499 | char filename [200], number[10]; 500 | 501 | if (dims<3) 502 | { 503 | ierr=PetscPrintf (PETSC_COMM_WORLD, 504 | "The 'd' command is for 3-D only.\n"); 505 | CHKERRQ (ierr); 506 | break; 507 | } 508 | 509 | strncpy (filename, basedirname, 198); 510 | strcat (filename, "/"); 511 | strncat (filename, files [current_entry], 198 - strlen (filename)); 512 | snprintf (number, 9, "-f%d", display_field); 513 | strncat (filename, number, 198 - strlen (filename)); 514 | strncat (filename, ".ppm", 198 - strlen (filename)); 515 | 516 | DPRINTF ("Saving image with filename %s\n", filename); 517 | IDispWritePPM (Disp, filename); 518 | break; 519 | } 520 | case 'a': 521 | case 'A': 522 | { 523 | char filename [200], number[10], *fieldname; 524 | int entry; 525 | 526 | if (dims<3) 527 | { 528 | ierr=PetscPrintf (PETSC_COMM_WORLD, 529 | "The 'a' command is for 3-D only.\n"); 530 | CHKERRQ (ierr); 531 | break; 532 | } 533 | 534 | for (entry=0; entry<total_entries; entry++) 535 | { 536 | DPRINTF ("Loading file %d/%d\r", entry, total_entries); 537 | strcpy (basis, basedirname); 538 | strcat (basis, "/"); 539 | strcat (basis, files[entry]); 540 | ierr = IlluMultiRead (PETSC_COMM_WORLD, theda, global, basis, 541 | &usermetacount, &usermetanames, 542 | &usermetadata); CHKERRQ (ierr); 543 | 544 | DPRINTF ("Rendering file %d/%d\r", entry, total_entries); 545 | ierr = DATriangulateRange 546 | (Surf, theda, global, display_field, minmax, 547 | plots?plots:PETSC_DECIDE, plots?plot_vals:PETSC_NULL, 548 | plots?plot_colors:PETSC_NULL, xmin,xmax, ymin,ymax, 549 | zmin,zmax); CHKERRQ (ierr); 550 | ierr = DAGetFieldName (theda, display_field, &fieldname); 551 | CHKERRQ (ierr); 552 | ierr = GeomviewDisplayTriangulation 553 | (PETSC_COMM_WORLD, Surf, Disp, minmax, fieldname, transp); 554 | CHKERRQ (ierr); 555 | ierr = SurfClear (Surf); CHKERRQ (ierr); 556 | 557 | DPRINTF ("Dumping file %d/%d\r", entry, total_entries); 558 | strncpy (filename, basedirname, 198); 559 | strcat (filename, "/"); 560 | strncat (filename, files [entry], 198 - strlen (filename)); 561 | snprintf (number, 9, "-f%d", display_field); 562 | strncat (filename, number, 198 - strlen (filename)); 563 | strncat (filename, ".ppm", 198 - strlen (filename)); 564 | IDispWritePPM (Disp, filename); 565 | } 566 | DPRINTF ("\n"); 567 | break; 568 | } 569 | #endif 570 | case 'r': 571 | case 'R': 572 | { 573 | total_entries = scandir (basedirname, &namelist, myfilter, 574 | alphasort); 575 | 576 | if (!(files = (char **) realloc (files,total_entries * sizeof (char *)))) 577 | { 578 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error allocating memory\n"); 579 | CHKERRQ (ierr); 580 | ierr = PetscFinalize (); CHKERRQ(ierr); 581 | return 1; 582 | } 583 | for (i=0; i<total_entries; i++) 584 | { 585 | int filength = strlen(namelist[i]->d_name); 586 | 587 | files [i] = (char *) malloc ((filength-12)*sizeof(char)); 588 | strncpy (files [i], namelist[i]->d_name, filength-13); 589 | files [i] [filength-13] = '\0'; 590 | free (namelist[i]); 591 | ierr = PetscPrintf (PETSC_COMM_WORLD, "[%d] %s\n", i, files [i]); 592 | CHKERRQ (ierr); 593 | } 594 | free (namelist); 595 | 596 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Total Entries: %d\n", 597 | total_entries); 598 | CHKERRQ (ierr); 599 | break; 600 | } 601 | case 's': 602 | case 'S': 603 | { 604 | if (instring[1] && instring[2] && dims<3) 605 | { 606 | sscanf (instring+2, "%d", &windowsize); 607 | 608 | if (windowsize) 609 | { 610 | int width=windowsize, height=windowsize; 611 | 612 | ierr = PetscViewerDestroy (theviewer); CHKERRQ (ierr); 613 | 614 | if (minmax[1]<minmax[3]) 615 | width *= minmax[1]/minmax[3]; 616 | else 617 | height *= minmax[3]/minmax[1]; 618 | 619 | ierr = PetscViewerDrawOpen 620 | (PETSC_COMM_WORLD, 0, "", PETSC_DECIDE, PETSC_DECIDE, 621 | width, height, &theviewer); CHKERRQ (ierr); 622 | } 623 | else 624 | { 625 | ierr=PetscPrintf (PETSC_COMM_WORLD, 626 | "Usage: \"s ###\" (2-D only)\n"); 627 | CHKERRQ (ierr); 628 | } 629 | } 630 | else 631 | { 632 | ierr=PetscPrintf (PETSC_COMM_WORLD, 633 | "Usage: \"s ###\" (2-D only)\n"); 634 | CHKERRQ (ierr); 635 | } 636 | break; 637 | } 638 | case 'p': 639 | case 'P': 640 | { 641 | int count=0, newplots=0; 642 | 643 | if (dims<3) 644 | { 645 | ierr=PetscPrintf (PETSC_COMM_WORLD, 646 | "The 'p' command is for 3-D only.\n"); 647 | CHKERRQ (ierr); 648 | break; 649 | } 650 | 651 | if (instring[1]=='\0' || instring[2]=='\0') 652 | { 653 | ierr = PetscPrintf (PETSC_COMM_WORLD, 654 | "Current plot contour isoquants:"); 655 | CHKERRQ (ierr); 656 | if (plots == 0) 657 | { 658 | ierr = PetscPrintf (PETSC_COMM_WORLD, 659 | " auto (20%%, 40%%, 60%%, 80%%)"); 660 | CHKERRQ (ierr); 661 | } 662 | for (count=0; count<plots; count++) 663 | { 664 | ierr = PetscPrintf (PETSC_COMM_WORLD, " %g", 665 | plot_vals[count]); CHKERRQ (ierr); 666 | } 667 | ierr = PetscPrintf (PETSC_COMM_WORLD, "\n"); CHKERRQ (ierr); 668 | break; 669 | } 670 | 671 | while (newplots<6 && instring[count] != '\0') 672 | { 673 | while ((instring[count] < '0' || instring[count] > '9') && 674 | instring[count] != '-' && instring[count] != '.' && 675 | instring[count] != '\0') 676 | count++; 677 | 678 | if (instring[count]) 679 | { 680 | #if defined(PETSC_USE_SINGLE) 681 | sscanf (instring+count, "%f", plot_vals+newplots); 682 | #else 683 | sscanf (instring+count, "%lf", plot_vals+newplots); 684 | #endif 685 | newplots++; 686 | while ((instring[count] >= '0' && instring[count] <= '9')|| 687 | instring[count] == '-' || instring[count] == '.') 688 | count++; 689 | } 690 | } 691 | plots = newplots; 692 | break; 693 | } 694 | case 'c': 695 | case 'C': 696 | { 697 | if (instring[1] == 'x' || instring[1] == 'X') 698 | xmax = (xmax == -2) ? -1 : -2; 699 | if (instring[1] == 'y' || instring[1] == 'Y') 700 | ymax = (ymax == -2) ? -1 : -2; 701 | if (instring[1] == 'z' || instring[1] == 'Z') 702 | zmax = (zmax == -2) ? -1 : -2; 703 | DPRINTF ("x %d-%d, y %d-%d, z %d-%d\n", xmin, xmax, ymin, ymax, 704 | zmin, zmax); 705 | break; 706 | } 707 | case 'g': 708 | case 'G': 709 | { 710 | int mingrid, maxgrid; 711 | sscanf (instring+2, "%d-%d", &mingrid, &maxgrid); 712 | if (instring[1] == 'x' || instring[1] == 'X') 713 | { 714 | xmin = mingrid; 715 | xmax = maxgrid; 716 | } 717 | if (instring[1] == 'y' || instring[1] == 'Y') 718 | { 719 | ymin = mingrid; 720 | ymax = maxgrid; 721 | } 722 | if (instring[1] == 'z' || instring[1] == 'Z') 723 | { 724 | zmin = mingrid; 725 | zmax = maxgrid; 726 | } 727 | DPRINTF ("x %d-%d, y %d-%d, z %d-%d\n", xmin, xmax, ymin, ymax, 728 | zmin, zmax); 729 | break; 730 | } 731 | default: 732 | current_entry+=increment; 733 | } 734 | if (current_entry < 0) 735 | current_entry = total_entries-1; 736 | if (current_entry >= total_entries) 737 | current_entry = 0; 738 | } 739 | 740 | free (filec); 741 | free (dirc); 742 | }