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