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 | }