1 | /***************************************
2 | $Header$
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=(instring[1]?atoi(instring+1):0); entry<total_entries;
535 | entry++)
536 | {
537 | ierr=PetscPrintf
538 | (PETSC_COMM_WORLD, "Loading file %d/%d\r", entry, total_entries);
539 | strcpy (basis, basedirname);
540 | strcat (basis, "/");
541 | strcat (basis, files[entry]);
542 | ierr = IlluMultiRead (PETSC_COMM_WORLD, theda, global, basis,
543 | &usermetacount, &usermetanames,
544 | &usermetadata); CHKERRQ (ierr);
545 |
546 | ierr=PetscPrintf
547 | (PETSC_COMM_WORLD, "Rendering file %d/%d\r", entry, total_entries);
548 | ierr = DATriangulateRange
549 | (Surf, theda, global, display_field, minmax,
550 | plots?plots:PETSC_DECIDE, plots?plot_vals:PETSC_NULL,
551 | plots?plot_colors:PETSC_NULL, xmin,xmax, ymin,ymax,
552 | zmin,zmax); CHKERRQ (ierr);
553 | ierr = DAGetFieldName (theda, display_field, &fieldname);
554 | CHKERRQ (ierr);
555 | ierr = GeomviewDisplayTriangulation
556 | (PETSC_COMM_WORLD, Surf, Disp, minmax, fieldname, transp);
557 | CHKERRQ (ierr);
558 | ierr = SurfClear (Surf); CHKERRQ (ierr);
559 |
560 | ierr=PetscPrintf
561 | (PETSC_COMM_WORLD, "Dumping file %d/%d\r", entry, total_entries);
562 | strncpy (filename, basedirname, 198);
563 | strcat (filename, "/");
564 | strncat (filename, files [entry], 198 - strlen (filename));
565 | snprintf (number, 9, "-f%d", display_field);
566 | strncat (filename, number, 198 - strlen (filename));
567 | strncat (filename, ".ppm", 198 - strlen (filename));
568 | IDispWritePPM (Disp, filename);
569 | }
570 | DPRINTF ("\n",0);
571 | break;
572 | }
573 | #endif
574 | case 'r':
575 | case 'R':
576 | {
577 | total_entries = scandir (basedirname, &namelist, myfilter,
578 | alphasort);
579 |
580 | if (!(files = (char **) realloc (files,total_entries * sizeof (char *))))
581 | {
582 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Error allocating memory\n");
583 | CHKERRQ (ierr);
584 | ierr = PetscFinalize (); CHKERRQ(ierr);
585 | return 1;
586 | }
587 | for (i=0; i<total_entries; i++)
588 | {
589 | int filength = strlen(namelist[i]->d_name);
590 |
591 | files [i] = (char *) malloc ((filength-12)*sizeof(char));
592 | strncpy (files [i], namelist[i]->d_name, filength-13);
593 | files [i] [filength-13] = '\0';
594 | free (namelist[i]);
595 | ierr = PetscPrintf (PETSC_COMM_WORLD, "[%d] %s\n", i, files [i]);
596 | CHKERRQ (ierr);
597 | }
598 | free (namelist);
599 |
600 | ierr = PetscPrintf (PETSC_COMM_WORLD, "Total Entries: %d\n",
601 | total_entries);
602 | CHKERRQ (ierr);
603 | break;
604 | }
605 | case 's':
606 | case 'S':
607 | {
608 | if (instring[1] && instring[2] && dims<3)
609 | {
610 | sscanf (instring+2, "%d", &windowsize);
611 |
612 | if (windowsize)
613 | {
614 | int width=windowsize, height=windowsize;
615 |
616 | ierr = PetscViewerDestroy (theviewer); CHKERRQ (ierr);
617 |
618 | if (minmax[1]<minmax[3])
619 | width *= minmax[1]/minmax[3];
620 | else
621 | height *= minmax[3]/minmax[1];
622 |
623 | ierr = PetscViewerDrawOpen
624 | (PETSC_COMM_WORLD, 0, "", PETSC_DECIDE, PETSC_DECIDE,
625 | width, height, &theviewer); CHKERRQ (ierr);
626 | }
627 | else
628 | {
629 | ierr=PetscPrintf (PETSC_COMM_WORLD,
630 | "Usage: \"s ###\" (2-D only)\n");
631 | CHKERRQ (ierr);
632 | }
633 | }
634 | else
635 | {
636 | ierr=PetscPrintf (PETSC_COMM_WORLD,
637 | "Usage: \"s ###\" (2-D only)\n");
638 | CHKERRQ (ierr);
639 | }
640 | break;
641 | }
642 | case 'p':
643 | case 'P':
644 | {
645 | int count=0, newplots=0;
646 |
647 | if (dims<3)
648 | {
649 | ierr=PetscPrintf (PETSC_COMM_WORLD,
650 | "The 'p' command is for 3-D only.\n");
651 | CHKERRQ (ierr);
652 | break;
653 | }
654 |
655 | if (instring[1]=='\0' || instring[2]=='\0')
656 | {
657 | ierr = PetscPrintf (PETSC_COMM_WORLD,
658 | "Current plot contour isoquants:");
659 | CHKERRQ (ierr);
660 | if (plots == 0)
661 | {
662 | ierr = PetscPrintf (PETSC_COMM_WORLD,
663 | " auto (20%%, 40%%, 60%%, 80%%)");
664 | CHKERRQ (ierr);
665 | }
666 | for (count=0; count<plots; count++)
667 | {
668 | ierr = PetscPrintf (PETSC_COMM_WORLD, " %g",
669 | plot_vals[count]); CHKERRQ (ierr);
670 | }
671 | ierr = PetscPrintf (PETSC_COMM_WORLD, "\n"); CHKERRQ (ierr);
672 | break;
673 | }
674 |
675 | while (newplots<6 && instring[count] != '\0')
676 | {
677 | while ((instring[count] < '0' || instring[count] > '9') &&
678 | instring[count] != '-' && instring[count] != '.' &&
679 | instring[count] != '\0')
680 | count++;
681 |
682 | if (instring[count])
683 | {
684 | #if defined(PETSC_USE_SINGLE)
685 | sscanf (instring+count, "%f", plot_vals+newplots);
686 | #else
687 | sscanf (instring+count, "%lf", plot_vals+newplots);
688 | #endif
689 | newplots++;
690 | while ((instring[count] >= '0' && instring[count] <= '9')||
691 | instring[count] == '-' || instring[count] == '.')
692 | count++;
693 | }
694 | }
695 | plots = newplots;
696 | break;
697 | }
698 | case 'c':
699 | case 'C':
700 | {
701 | if (instring[1] == 'x' || instring[1] == 'X')
702 | xmax = (xmax == -2) ? -1 : -2;
703 | if (instring[1] == 'y' || instring[1] == 'Y')
704 | ymax = (ymax == -2) ? -1 : -2;
705 | if (instring[1] == 'z' || instring[1] == 'Z')
706 | zmax = (zmax == -2) ? -1 : -2;
707 | DPRINTF ("x %d-%d, y %d-%d, z %d-%d\n", xmin, xmax, ymin, ymax,
708 | zmin, zmax);
709 | break;
710 | }
711 | case 'g':
712 | case 'G':
713 | {
714 | int mingrid, maxgrid;
715 | sscanf (instring+2, "%d-%d", &mingrid, &maxgrid);
716 | if (instring[1] == 'x' || instring[1] == 'X')
717 | {
718 | xmin = mingrid;
719 | xmax = maxgrid;
720 | }
721 | if (instring[1] == 'y' || instring[1] == 'Y')
722 | {
723 | ymin = mingrid;
724 | ymax = maxgrid;
725 | }
726 | if (instring[1] == 'z' || instring[1] == 'Z')
727 | {
728 | zmin = mingrid;
729 | zmax = maxgrid;
730 | }
731 | DPRINTF ("x %d-%d, y %d-%d, z %d-%d\n", xmin, xmax, ymin, ymax,
732 | zmin, zmax);
733 | break;
734 | }
735 | default:
736 | current_entry+=increment;
737 | }
738 | if (current_entry < 0)
739 | current_entry = total_entries-1;
740 | if (current_entry >= total_entries)
741 | current_entry = 0;
742 | }
743 |
744 | free (filec);
745 | free (dirc);
746 | }