xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 7c8652dd9fb051dfaf30896d504f41ba028df3ea)
1 
2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I "petscviewer.h" I*/
3 
4 #define QUEUESTRINGSIZE 8192
5 
6 #undef __FUNCT__
7 #define __FUNCT__ "PetscViewerFileClose_ASCII"
8 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
9 {
10   PetscErrorCode    ierr;
11   PetscMPIInt       rank;
12   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
13   int               err;
14 
15   PetscFunctionBegin;
16   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
17   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
18     if (vascii->fd && vascii->closefile) {
19       err = fclose(vascii->fd);
20       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
21     }
22     if (vascii->storecompressed) {
23       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
24       FILE *fp;
25       ierr = PetscStrcpy(par,"gzip ");CHKERRQ(ierr);
26       ierr = PetscStrcat(par,vascii->filename);CHKERRQ(ierr);
27 #if defined(PETSC_HAVE_POPEN)
28       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr);
29       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
30       ierr = PetscPClose(PETSC_COMM_SELF,fp,NULL);CHKERRQ(ierr);
31 #else
32       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
33 #endif
34     }
35   }
36   ierr = PetscFree(vascii->filename);CHKERRQ(ierr);
37   PetscFunctionReturn(0);
38 }
39 
40 /* ----------------------------------------------------------------------*/
41 #undef __FUNCT__
42 #define __FUNCT__ "PetscViewerDestroy_ASCII"
43 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
44 {
45   PetscErrorCode    ierr;
46   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
47   PetscViewerLink   *vlink;
48   PetscBool         flg;
49 
50   PetscFunctionBegin;
51   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
52   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
53   ierr = PetscFree(vascii);CHKERRQ(ierr);
54 
55   /* remove the viewer from the list in the MPI Communicator */
56   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
57     ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
58   }
59 
60   ierr = MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
61   if (flg) {
62     if (vlink && vlink->viewer == viewer) {
63       ierr = MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr);
64       ierr = PetscFree(vlink);CHKERRQ(ierr);
65     } else {
66       while (vlink && vlink->next) {
67         if (vlink->next->viewer == viewer) {
68           PetscViewerLink *nv = vlink->next;
69           vlink->next = vlink->next->next;
70           ierr = PetscFree(nv);CHKERRQ(ierr);
71         }
72         vlink = vlink->next;
73       }
74     }
75   }
76   PetscFunctionReturn(0);
77 }
78 
79 #undef __FUNCT__
80 #define __FUNCT__ "PetscViewerDestroy_ASCII_Singleton"
81 PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
82 {
83   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
84   PetscErrorCode    ierr;
85 
86   PetscFunctionBegin;
87   ierr = PetscViewerRestoreSingleton(vascii->bviewer,&viewer);CHKERRQ(ierr);
88   vascii->bviewer = NULL;
89   PetscFunctionReturn(0);
90 }
91 
92 #undef __FUNCT__
93 #define __FUNCT__ "PetscViewerDestroy_ASCII_Subcomm"
94 PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
95 {
96   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
97   PetscErrorCode    ierr;
98 
99   PetscFunctionBegin;
100   ierr = PetscViewerRestoreSubcomm(vascii->subviewer,PetscObjectComm((PetscObject)viewer),&viewer);CHKERRQ(ierr);
101   vascii->subviewer = NULL;
102   PetscFunctionReturn(0);
103 }
104 
105 #undef __FUNCT__
106 #define __FUNCT__ "PetscViewerFlush_ASCII_Singleton_0"
107 PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
108 {
109   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
110   int               err;
111 
112   PetscFunctionBegin;
113   err = fflush(vascii->fd);
114   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
115   PetscFunctionReturn(0);
116 }
117 
118 #undef __FUNCT__
119 #define __FUNCT__ "PetscViewerFlush_ASCII"
120 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
121 {
122   PetscMPIInt       rank;
123   PetscErrorCode    ierr;
124   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
125   int               err;
126 
127   PetscFunctionBegin;
128   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
129   /* fflush() fails on OSX for read-only descriptors */
130   if (!rank && (vascii->mode != FILE_MODE_READ)) {
131     err = fflush(vascii->fd);
132     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
133   }
134 
135   if (vascii->allowsynchronized) {
136     /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf()  */
137     ierr = PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer),vascii->fd);CHKERRQ(ierr);
138   }
139   PetscFunctionReturn(0);
140 }
141 
142 #undef __FUNCT__
143 #define __FUNCT__ "PetscViewerASCIIGetPointer"
144 /*@C
145     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
146 
147     Not Collective
148 
149 +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
150 -   fd - file pointer
151 
152     Level: intermediate
153 
154     Fortran Note:
155     This routine is not supported in Fortran.
156 
157   Concepts: PetscViewer^file pointer
158   Concepts: file pointer^getting from PetscViewer
159 
160 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
161           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
162 @*/
163 PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
164 {
165   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
166 
167   PetscFunctionBegin;
168   *fd = vascii->fd;
169   PetscFunctionReturn(0);
170 }
171 
172 #undef __FUNCT__
173 #define __FUNCT__ "PetscViewerFileGetMode_ASCII"
174 PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
175 {
176   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
177 
178   PetscFunctionBegin;
179   *mode = vascii->mode;
180   PetscFunctionReturn(0);
181 }
182 
183 #undef __FUNCT__
184 #define __FUNCT__ "PetscViewerFileSetMode_ASCII"
185 PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
186 {
187   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
188 
189   PetscFunctionBegin;
190   vascii->mode = mode;
191   PetscFunctionReturn(0);
192 }
193 
194 /*
195    If petsc_history is on, then all Petsc*Printf() results are saved
196    if the appropriate (usually .petschistory) file.
197 */
198 extern FILE *petsc_history;
199 
200 #undef __FUNCT__
201 #define __FUNCT__ "PetscViewerASCIISetTab"
202 /*@
203     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
204 
205     Not Collective, but only first processor in set has any effect
206 
207     Input Parameters:
208 +    viewer - optained with PetscViewerASCIIOpen()
209 -    tabs - number of tabs
210 
211     Level: developer
212 
213     Fortran Note:
214     This routine is not supported in Fortran.
215 
216   Concepts: PetscViewerASCII^formating
217   Concepts: tab^setting
218 
219 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
220           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
221           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
222 @*/
223 PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
224 {
225   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
226   PetscBool         iascii;
227   PetscErrorCode    ierr;
228 
229   PetscFunctionBegin;
230   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
231   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
232   if (iascii) ascii->tab = tabs;
233   PetscFunctionReturn(0);
234 }
235 
236 #undef __FUNCT__
237 #define __FUNCT__ "PetscViewerASCIIGetTab"
238 /*@
239     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
240 
241     Not Collective, meaningful on first processor only.
242 
243     Input Parameters:
244 .    viewer - optained with PetscViewerASCIIOpen()
245     Output Parameters:
246 .    tabs - number of tabs
247 
248     Level: developer
249 
250     Fortran Note:
251     This routine is not supported in Fortran.
252 
253   Concepts: PetscViewerASCII^formating
254   Concepts: tab^retrieval
255 
256 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
257           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259 @*/
260 PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
261 {
262   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
263   PetscBool         iascii;
264   PetscErrorCode    ierr;
265 
266   PetscFunctionBegin;
267   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
268   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
269   if (iascii && tabs) *tabs = ascii->tab;
270   PetscFunctionReturn(0);
271 }
272 
273 #undef __FUNCT__
274 #define __FUNCT__ "PetscViewerASCIIAddTab"
275 /*@
276     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
277 
278     Not Collective, but only first processor in set has any effect
279 
280     Input Parameters:
281 +    viewer - optained with PetscViewerASCIIOpen()
282 -    tabs - number of tabs
283 
284     Level: developer
285 
286     Fortran Note:
287     This routine is not supported in Fortran.
288 
289   Concepts: PetscViewerASCII^formating
290   Concepts: tab^setting
291 
292 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
293           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
294           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
295 @*/
296 PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
297 {
298   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
299   PetscBool         iascii;
300   PetscErrorCode    ierr;
301 
302   PetscFunctionBegin;
303   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
304   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
305   if (iascii) ascii->tab += tabs;
306   PetscFunctionReturn(0);
307 }
308 
309 #undef __FUNCT__
310 #define __FUNCT__ "PetscViewerASCIISubtractTab"
311 /*@
312     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
313 
314     Not Collective, but only first processor in set has any effect
315 
316     Input Parameters:
317 +    viewer - optained with PetscViewerASCIIOpen()
318 -    tabs - number of tabs
319 
320     Level: developer
321 
322     Fortran Note:
323     This routine is not supported in Fortran.
324 
325   Concepts: PetscViewerASCII^formating
326   Concepts: tab^setting
327 
328 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
329           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
330           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
331 @*/
332 PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
333 {
334   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
335   PetscBool         iascii;
336   PetscErrorCode    ierr;
337 
338   PetscFunctionBegin;
339   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
340   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
341   if (iascii) ascii->tab -= tabs;
342   PetscFunctionReturn(0);
343 }
344 
345 #undef __FUNCT__
346 #define __FUNCT__ "PetscViewerASCIISynchronizedAllow"
347 /*@C
348     PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
349 
350     Collective on PetscViewer
351 
352     Input Parameters:
353 +    viewer - optained with PetscViewerASCIIOpen()
354 -    allow - PETSC_TRUE to allow the synchronized printing
355 
356     Level: intermediate
357 
358   Concepts: PetscViewerASCII^formating
359   Concepts: tab^setting
360 
361 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
362           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
363           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
364 @*/
365 PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
366 {
367   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
368   PetscBool         iascii;
369   PetscErrorCode    ierr;
370 
371   PetscFunctionBegin;
372   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
373   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
374   if (iascii) ascii->allowsynchronized = allow;
375   PetscFunctionReturn(0);
376 }
377 
378 #undef __FUNCT__
379 #define __FUNCT__ "PetscViewerASCIIPushTab"
380 /*@
381     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
382      lines are tabbed.
383 
384     Not Collective, but only first processor in set has any effect
385 
386     Input Parameters:
387 .    viewer - optained with PetscViewerASCIIOpen()
388 
389     Level: developer
390 
391     Fortran Note:
392     This routine is not supported in Fortran.
393 
394   Concepts: PetscViewerASCII^formating
395   Concepts: tab^setting
396 
397 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
398           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
399           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
400 @*/
401 PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
402 {
403   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
404   PetscBool         iascii;
405   PetscErrorCode    ierr;
406 
407   PetscFunctionBegin;
408   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
409   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
410   if (iascii) ascii->tab++;
411   PetscFunctionReturn(0);
412 }
413 
414 #undef __FUNCT__
415 #define __FUNCT__ "PetscViewerASCIIPopTab"
416 /*@
417     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
418      lines are tabbed.
419 
420     Not Collective, but only first processor in set has any effect
421 
422     Input Parameters:
423 .    viewer - optained with PetscViewerASCIIOpen()
424 
425     Level: developer
426 
427     Fortran Note:
428     This routine is not supported in Fortran.
429 
430   Concepts: PetscViewerASCII^formating
431   Concepts: tab^setting
432 
433 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
434           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
435           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
436 @*/
437 PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
438 {
439   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
440   PetscErrorCode    ierr;
441   PetscBool         iascii;
442 
443   PetscFunctionBegin;
444   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
445   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
446   if (iascii) {
447     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
448     ascii->tab--;
449   }
450   PetscFunctionReturn(0);
451 }
452 
453 #undef __FUNCT__
454 #define __FUNCT__ "PetscViewerASCIIUseTabs"
455 /*@
456     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
457 
458     Not Collective, but only first processor in set has any effect
459 
460     Input Parameters:
461 +    viewer - optained with PetscViewerASCIIOpen()
462 -    flg - PETSC_TRUE or PETSC_FALSE
463 
464     Level: developer
465 
466     Fortran Note:
467     This routine is not supported in Fortran.
468 
469   Concepts: PetscViewerASCII^formating
470   Concepts: tab^setting
471 
472 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
473           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
474           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
475 @*/
476 PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
477 {
478   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
479   PetscBool         iascii;
480   PetscErrorCode    ierr;
481 
482   PetscFunctionBegin;
483   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
484   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
485   if (iascii) {
486     if (flg) ascii->tab = ascii->tab_store;
487     else {
488       ascii->tab_store = ascii->tab;
489       ascii->tab       = 0;
490     }
491   }
492   PetscFunctionReturn(0);
493 }
494 
495 /* ----------------------------------------------------------------------- */
496 
497 #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
498 
499 #undef __FUNCT__
500 #define __FUNCT__ "PetscViewerASCIIPrintf"
501 /*@C
502     PetscViewerASCIIPrintf - Prints to a file, only from the first
503     processor in the PetscViewer
504 
505     Not Collective, but only first processor in set has any effect
506 
507     Input Parameters:
508 +    viewer - optained with PetscViewerASCIIOpen()
509 -    format - the usual printf() format string
510 
511     Level: developer
512 
513     Fortran Note:
514     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
515     That is, you can only pass a single character string from Fortran.
516 
517   Concepts: PetscViewerASCII^printing
518   Concepts: printing^to file
519   Concepts: printf
520 
521 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
522           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
523           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
524 @*/
525 PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
526 {
527   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
528   PetscMPIInt       rank;
529   PetscInt          tab,intab = ascii->tab;
530   PetscErrorCode    ierr;
531   FILE              *fd = ascii->fd;
532   PetscBool         iascii,issingleton = PETSC_FALSE;
533   int               err;
534 
535   PetscFunctionBegin;
536   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
537   PetscValidCharPointer(format,2);
538   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
539   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
540   if (ascii->bviewer) {
541     viewer      = ascii->bviewer;
542     ascii       = (PetscViewer_ASCII*)viewer->data;
543     fd          = ascii->fd;
544     issingleton = PETSC_TRUE;
545   }
546 
547   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
548   if (!rank) {
549     va_list Argp;
550     tab = intab;
551     while (tab--) {
552       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
553     }
554 
555     va_start(Argp,format);
556     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
557     err  = fflush(fd);
558     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
559     if (petsc_history) {
560       va_start(Argp,format);
561       tab = intab;
562       while (tab--) {
563         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
564       }
565       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
566       err  = fflush(petsc_history);
567       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
568     }
569     va_end(Argp);
570   } else if (issingleton) {
571     char        *string;
572     va_list     Argp;
573     size_t      fullLength;
574     PrintfQueue next;
575 
576     ierr = PetscNew(&next);CHKERRQ(ierr);
577     if (petsc_printfqueue) {
578       petsc_printfqueue->next = next;
579       petsc_printfqueue       = next;
580     } else {
581       petsc_printfqueuebase = petsc_printfqueue = next;
582     }
583     petsc_printfqueuelength++;
584     next->size = QUEUESTRINGSIZE;
585     ierr       = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr);
586     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
587     string     = next->string;
588     tab        = intab;
589     tab       *= 2;
590     while (tab--) {
591       *string++ = ' ';
592     }
593     va_start(Argp,format);
594     ierr = PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
595     va_end(Argp);
596   }
597   PetscFunctionReturn(0);
598 }
599 
600 #undef __FUNCT__
601 #define __FUNCT__ "PetscViewerFileSetName"
602 /*@C
603      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
604 
605     Collective on PetscViewer
606 
607   Input Parameters:
608 +  viewer - the PetscViewer; either ASCII or binary
609 -  name - the name of the file it should use
610 
611     Level: advanced
612 
613 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
614           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
615 
616 @*/
617 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
618 {
619   PetscErrorCode ierr;
620 
621   PetscFunctionBegin;
622   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
623   PetscValidCharPointer(name,2);
624   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr);
625   PetscFunctionReturn(0);
626 }
627 
628 #undef __FUNCT__
629 #define __FUNCT__ "PetscViewerFileGetName"
630 /*@C
631      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
632 
633     Not Collective
634 
635   Input Parameter:
636 .  viewer - the PetscViewer; either ASCII or binary
637 
638   Output Parameter:
639 .  name - the name of the file it is using
640 
641     Level: advanced
642 
643 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
644 
645 @*/
646 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
647 {
648   PetscErrorCode ierr;
649 
650   PetscFunctionBegin;
651   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
652   ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
653   PetscFunctionReturn(0);
654 }
655 
656 #undef __FUNCT__
657 #define __FUNCT__ "PetscViewerFileGetName_ASCII"
658 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
659 {
660   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
661 
662   PetscFunctionBegin;
663   *name = vascii->filename;
664   PetscFunctionReturn(0);
665 }
666 
667 #undef __FUNCT__
668 #define __FUNCT__ "PetscViewerFileSetName_ASCII"
669 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
670 {
671   PetscErrorCode    ierr;
672   size_t            len;
673   char              fname[PETSC_MAX_PATH_LEN],*gz;
674   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
675   PetscBool         isstderr,isstdout;
676   PetscMPIInt       rank;
677 
678   PetscFunctionBegin;
679   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
680   if (!name) PetscFunctionReturn(0);
681   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
682 
683   /* Is this file to be compressed */
684   vascii->storecompressed = PETSC_FALSE;
685 
686   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
687   if (gz) {
688     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
689     if (len == 3) {
690       *gz = 0;
691       vascii->storecompressed = PETSC_TRUE;
692     }
693   }
694   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
695   if (!rank) {
696     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
697     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
698     /* empty filename means stdout */
699     if (name[0] == 0)  isstdout = PETSC_TRUE;
700     if (isstderr)      vascii->fd = PETSC_STDERR;
701     else if (isstdout) vascii->fd = PETSC_STDOUT;
702     else {
703 
704 
705       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
706       switch (vascii->mode) {
707       case FILE_MODE_READ:
708         vascii->fd = fopen(fname,"r");
709         break;
710       case FILE_MODE_WRITE:
711         vascii->fd = fopen(fname,"w");
712         break;
713       case FILE_MODE_APPEND:
714         vascii->fd = fopen(fname,"a");
715         break;
716       case FILE_MODE_UPDATE:
717         vascii->fd = fopen(fname,"r+");
718         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
719         break;
720       case FILE_MODE_APPEND_UPDATE:
721         /* I really want a file which is opened at the end for updating,
722            not a+, which opens at the beginning, but makes writes at the end.
723         */
724         vascii->fd = fopen(fname,"r+");
725         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
726         else {
727           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
728         }
729         break;
730       default:
731         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
732       }
733       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
734     }
735   }
736 #if defined(PETSC_USE_LOG)
737   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
738 #endif
739   PetscFunctionReturn(0);
740 }
741 
742 #undef __FUNCT__
743 #define __FUNCT__ "PetscViewerGetSingleton_ASCII"
744 PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
745 {
746   PetscMPIInt       rank;
747   PetscErrorCode    ierr;
748   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
749   const char        *name;
750 
751   PetscFunctionBegin;
752   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
753   ierr         = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr);
754   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
755   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
756   ovascii->fd  = vascii->fd;
757   ovascii->tab = vascii->tab;
758 
759   vascii->sviewer = *outviewer;
760 
761   (*outviewer)->format  = viewer->format;
762 
763   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
764   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
765 
766   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
767   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
768   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
769   if (rank) (*outviewer)->ops->flush = 0;
770   else      (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
771   PetscFunctionReturn(0);
772 }
773 
774 #undef __FUNCT__
775 #define __FUNCT__ "PetscViewerRestoreSingleton_ASCII"
776 PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
777 {
778   PetscErrorCode    ierr;
779   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
780   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
781 
782   PetscFunctionBegin;
783   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
784   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
785 
786   ascii->sviewer             = 0;
787   vascii->fd                 = PETSC_STDOUT;
788   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
789   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
790   ierr                       = PetscViewerFlush(viewer);CHKERRQ(ierr);
791   PetscFunctionReturn(0);
792 }
793 
794 #undef __FUNCT__
795 #define __FUNCT__ "PetscViewerGetSubcomm_ASCII"
796 PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
797 {
798   PetscErrorCode    ierr;
799   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
800   const char        *name;
801 
802   PetscFunctionBegin;
803   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
804   /* Note that we need to open vascii->filename for the subcomm:
805      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
806      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
807      will return the current viewer, having increfed it.
808    */
809   ierr = PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);CHKERRQ(ierr);
810   if (*outviewer == viewer) PetscFunctionReturn(0);
811   ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
812 
813   ovascii->tab    = vascii->tab;
814   vascii->sviewer = *outviewer;
815 
816   (*outviewer)->format  = viewer->format;
817 
818   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
819   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
820 
821   ((PetscViewer_ASCII*)((*outviewer)->data))->subviewer = viewer;
822 
823   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
824   PetscFunctionReturn(0);
825 }
826 
827 #undef __FUNCT__
828 #define __FUNCT__ "PetscViewerRestoreSubcomm_ASCII"
829 PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
830 {
831   PetscErrorCode    ierr;
832   PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
833   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
834 
835   PetscFunctionBegin;
836   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
837   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
838 
839   ascii->sviewer             = 0;
840   oascii->fd                 = PETSC_STDOUT;
841   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
842 
843   ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
844   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
845   PetscFunctionReturn(0);
846 }
847 
848 #undef __FUNCT__
849 #define __FUNCT__ "PetscViewerView_ASCII"
850 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
851 {
852   PetscErrorCode    ierr;
853   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
854 
855   PetscFunctionBegin;
856   if (ascii->filename) {
857     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
858   }
859   PetscFunctionReturn(0);
860 }
861 
862 #undef __FUNCT__
863 #define __FUNCT__ "PetscViewerCreate_ASCII"
864 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
865 {
866   PetscViewer_ASCII *vascii;
867   PetscErrorCode    ierr;
868 
869   PetscFunctionBegin;
870   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
871   viewer->data = (void*)vascii;
872 
873   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
874   viewer->ops->flush            = PetscViewerFlush_ASCII;
875   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
876   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
877   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
878   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;
879   viewer->ops->view             = PetscViewerView_ASCII;
880 
881   /* defaults to stdout unless set with PetscViewerFileSetName() */
882   vascii->fd        = PETSC_STDOUT;
883   vascii->mode      = FILE_MODE_WRITE;
884   vascii->bviewer   = 0;
885   vascii->subviewer = 0;
886   vascii->sviewer   = 0;
887   vascii->tab       = 0;
888   vascii->tab_store = 0;
889   vascii->filename  = 0;
890   vascii->closefile = PETSC_TRUE;
891 
892   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
893   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
894   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
895   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
896   PetscFunctionReturn(0);
897 }
898 
899 
900 #undef __FUNCT__
901 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
902 /*@C
903     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
904     several processors.  Output of the first processor is followed by that of the
905     second, etc.
906 
907     Not Collective, must call collective PetscViewerFlush() to get the results out
908 
909     Input Parameters:
910 +   viewer - the ASCII PetscViewer
911 -   format - the usual printf() format string
912 
913     Level: intermediate
914 
915     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
916 
917     Fortran Note:
918       Can only print a single character* string
919 
920 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
921           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
922           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
923 
924 @*/
925 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
926 {
927   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
928   PetscErrorCode    ierr;
929   PetscMPIInt       rank,size;
930   PetscInt          tab = vascii->tab;
931   MPI_Comm          comm;
932   FILE              *fp;
933   PetscBool         iascii;
934   int               err;
935 
936   PetscFunctionBegin;
937   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
938   PetscValidCharPointer(format,2);
939   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
940   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
941   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
942   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
943   if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
944 
945   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
946   fp   = vascii->fd;
947   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
948 
949   /* First processor prints immediately to fp */
950   if (!rank) {
951     va_list Argp;
952 
953     while (tab--) {
954       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
955     }
956 
957     va_start(Argp,format);
958     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
959     err  = fflush(fp);
960     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
961     if (petsc_history) {
962       va_start(Argp,format);
963       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
964       err  = fflush(petsc_history);
965       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
966     }
967     va_end(Argp);
968   } else { /* other processors add to local queue */
969     char        *string;
970     va_list     Argp;
971     size_t      fullLength;
972     PrintfQueue next;
973 
974     ierr = PetscNew(&next);CHKERRQ(ierr);
975     if (petsc_printfqueue) {
976       petsc_printfqueue->next = next;
977       petsc_printfqueue       = next;
978     } else {
979       petsc_printfqueuebase = petsc_printfqueue = next;
980     }
981     petsc_printfqueuelength++;
982     next->size = QUEUESTRINGSIZE;
983     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
984     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
985     string     = next->string;
986     tab       *= 2;
987     while (tab--) {
988       *string++ = ' ';
989     }
990     va_start(Argp,format);
991     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
992     va_end(Argp);
993   }
994   PetscFunctionReturn(0);
995 }
996 
997 
998