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