xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision e383bbd07f1c175fdb04eea9fdcaf8d9f9e92c0f)
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 #undef __FUNCT__
861 #define __FUNCT__ "PetscViewerView_ASCII"
862 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
863 {
864   PetscErrorCode     ierr;
865   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)v->data;
866 
867   PetscFunctionBegin;
868   if (ascii->filename) {
869     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
870   }
871   PetscFunctionReturn(0);
872 }
873 
874 EXTERN_C_BEGIN
875 #undef __FUNCT__
876 #define __FUNCT__ "PetscViewerCreate_ASCII"
877 PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
878 {
879   PetscViewer_ASCII *vascii;
880   PetscErrorCode    ierr;
881 
882   PetscFunctionBegin;
883   ierr         = PetscNewLog(viewer,PetscViewer_ASCII,&vascii);CHKERRQ(ierr);
884   viewer->data = (void*)vascii;
885 
886   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
887   viewer->ops->flush            = PetscViewerFlush_ASCII;
888   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
889   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
890   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
891   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;
892   viewer->ops->view             = PetscViewerView_ASCII;
893 
894   /* defaults to stdout unless set with PetscViewerFileSetName() */
895   vascii->fd             = PETSC_STDOUT;
896   vascii->mode           = FILE_MODE_WRITE;
897   vascii->bviewer        = 0;
898   vascii->sviewer        = 0;
899   viewer->format         = PETSC_VIEWER_DEFAULT;
900   viewer->iformat        = 0;
901   vascii->tab            = 0;
902   vascii->tab_store      = 0;
903   vascii->filename       = 0;
904   vascii->closefile      = PETSC_TRUE;
905 
906   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
907                                      PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
908   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
909                                      PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
910   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
911                                      PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
912   ierr = PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
913                                      PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
914 
915   PetscFunctionReturn(0);
916 }
917 EXTERN_C_END
918 
919 
920 #undef __FUNCT__
921 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
922 /*@C
923     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
924     several processors.  Output of the first processor is followed by that of the
925     second, etc.
926 
927     Not Collective, must call collective PetscViewerFlush() to get the results out
928 
929     Input Parameters:
930 +   viewer - the ASCII PetscViewer
931 -   format - the usual printf() format string
932 
933     Level: intermediate
934 
935     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
936 
937     Fortran Note:
938       Can only print a single character* string
939 
940 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
941           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
942           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
943 
944 @*/
945 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
946 {
947   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
948   PetscErrorCode    ierr;
949   PetscMPIInt       rank,size;
950   PetscInt          tab = vascii->tab;
951   MPI_Comm          comm;
952   FILE              *fp;
953   PetscBool         iascii;
954   int               err;
955 
956   PetscFunctionBegin;
957   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
958   PetscValidCharPointer(format,2);
959   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
960   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
961   ierr = MPI_Comm_size(((PetscObject)viewer)->comm,&size);CHKERRQ(ierr);
962   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
963   if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
964 
965   comm = ((PetscObject)viewer)->comm;
966   fp   = vascii->fd;
967   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
968 
969   /* First processor prints immediately to fp */
970   if (!rank) {
971     va_list Argp;
972 
973     while (tab--) {ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);}
974 
975     va_start(Argp,format);
976     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
977     err = fflush(fp);
978     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
979     petsc_printfqueuefile = fp;
980     if (petsc_history) {
981       va_start(Argp,format);
982       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
983       err = fflush(petsc_history);
984       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
985     }
986     va_end(Argp);
987   } else { /* other processors add to local queue */
988     char        *string;
989     va_list     Argp;
990     size_t      fullLength;
991     PrintfQueue next;
992 
993     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
994     if (petsc_printfqueue) {petsc_printfqueue->next = next; petsc_printfqueue = next;}
995     else                   {petsc_printfqueuebase   = petsc_printfqueue = next;}
996     petsc_printfqueuelength++;
997     next->size = QUEUESTRINGSIZE;
998     ierr = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr);
999     ierr = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
1000     string = next->string;
1001     tab *= 2;
1002     while (tab--) {*string++ = ' ';}
1003     va_start(Argp,format);
1004     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1005     va_end(Argp);
1006   }
1007   PetscFunctionReturn(0);
1008 }
1009 
1010 
1011