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