xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision e6abc3dd0fc68e500528c537b91e218911726ee2)
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     Output Parameters:
285 .    tabs - number of tabs
286 
287     Level: developer
288 
289     Fortran Note:
290     This routine is not supported in Fortran.
291 
292   Concepts: PetscViewerASCII^formating
293   Concepts: tab^retrieval
294 
295 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
296           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
297           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
298 @*/
299 PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
300 {
301   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
302   PetscBool         iascii;
303   PetscErrorCode    ierr;
304 
305   PetscFunctionBegin;
306   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
307   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
308   if (iascii && tabs) *tabs = ascii->tab;
309   PetscFunctionReturn(0);
310 }
311 
312 /*@
313     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
314 
315     Not Collective, but only first processor in set has any effect
316 
317     Input Parameters:
318 +    viewer - obtained with PetscViewerASCIIOpen()
319 -    tabs - number of tabs
320 
321     Level: developer
322 
323     Fortran Note:
324     This routine is not supported in Fortran.
325 
326   Concepts: PetscViewerASCII^formating
327   Concepts: tab^setting
328 
329 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
330           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
331           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
332 @*/
333 PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
334 {
335   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
336   PetscBool         iascii;
337   PetscErrorCode    ierr;
338 
339   PetscFunctionBegin;
340   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
341   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
342   if (iascii) ascii->tab += tabs;
343   PetscFunctionReturn(0);
344 }
345 
346 /*@
347     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
348 
349     Not Collective, but only first processor in set has any effect
350 
351     Input Parameters:
352 +    viewer - obtained with PetscViewerASCIIOpen()
353 -    tabs - number of tabs
354 
355     Level: developer
356 
357     Fortran Note:
358     This routine is not supported in Fortran.
359 
360   Concepts: PetscViewerASCII^formating
361   Concepts: tab^setting
362 
363 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
364           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
365           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
366 @*/
367 PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
368 {
369   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
370   PetscBool         iascii;
371   PetscErrorCode    ierr;
372 
373   PetscFunctionBegin;
374   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
375   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
376   if (iascii) ascii->tab -= tabs;
377   PetscFunctionReturn(0);
378 }
379 
380 /*@C
381     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
382 
383     Collective on PetscViewer
384 
385     Input Parameters:
386 .    viewer - obtained with PetscViewerASCIIOpen()
387 
388     Level: intermediate
389 
390     Notes:
391     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
392 
393   Concepts: PetscViewerASCII^formating
394   Concepts: tab^setting
395 
396 .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
397           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
398           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
399 @*/
400 PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
401 {
402   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
403   PetscBool         iascii;
404   PetscErrorCode    ierr;
405 
406   PetscFunctionBegin;
407   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
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     Notes:
424     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
425 
426   Concepts: PetscViewerASCII^formating
427   Concepts: tab^setting
428 
429 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
430           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
431           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
432 @*/
433 PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
434 {
435   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
436   PetscBool         iascii;
437   PetscErrorCode    ierr;
438 
439   PetscFunctionBegin;
440   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
441   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
442   if (iascii) {
443     ascii->allowsynchronized--;
444     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
445   }
446   PetscFunctionReturn(0);
447 }
448 
449 /*@C
450     PetscViewerASCIIPushTab - Adds one more tab to 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 - obtained 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           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
468           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469 @*/
470 PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
471 {
472   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473   PetscBool         iascii;
474   PetscErrorCode    ierr;
475 
476   PetscFunctionBegin;
477   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
478   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
479   if (iascii) ascii->tab++;
480   PetscFunctionReturn(0);
481 }
482 
483 /*@C
484     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
485      lines are tabbed.
486 
487     Not Collective, but only first processor in set has any effect
488 
489     Input Parameters:
490 .    viewer - obtained with PetscViewerASCIIOpen()
491 
492     Level: developer
493 
494     Fortran Note:
495     This routine is not supported in Fortran.
496 
497   Concepts: PetscViewerASCII^formating
498   Concepts: tab^setting
499 
500 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
501           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
502           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
503 @*/
504 PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
505 {
506   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
507   PetscErrorCode    ierr;
508   PetscBool         iascii;
509 
510   PetscFunctionBegin;
511   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
512   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
513   if (iascii) {
514     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
515     ascii->tab--;
516   }
517   PetscFunctionReturn(0);
518 }
519 
520 /*@
521     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
522 
523     Not Collective, but only first processor in set has any effect
524 
525     Input Parameters:
526 +    viewer - obtained with PetscViewerASCIIOpen()
527 -    flg - PETSC_TRUE or PETSC_FALSE
528 
529     Level: developer
530 
531     Fortran Note:
532     This routine is not supported in Fortran.
533 
534   Concepts: PetscViewerASCII^formating
535   Concepts: tab^setting
536 
537 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
538           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
539           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
540 @*/
541 PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
542 {
543   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
544   PetscBool         iascii;
545   PetscErrorCode    ierr;
546 
547   PetscFunctionBegin;
548   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
549   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
550   if (iascii) {
551     if (flg) ascii->tab = ascii->tab_store;
552     else {
553       ascii->tab_store = ascii->tab;
554       ascii->tab       = 0;
555     }
556   }
557   PetscFunctionReturn(0);
558 }
559 
560 /* ----------------------------------------------------------------------- */
561 
562 
563 /*@C
564     PetscViewerASCIIPrintf - Prints to a file, only from the first
565     processor in the PetscViewer
566 
567     Not Collective, but only first processor in set has any effect
568 
569     Input Parameters:
570 +    viewer - obtained with PetscViewerASCIIOpen()
571 -    format - the usual printf() format string
572 
573     Level: developer
574 
575     Fortran Note:
576     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
577     That is, you can only pass a single character string from Fortran.
578 
579   Concepts: PetscViewerASCII^printing
580   Concepts: printing^to file
581   Concepts: printf
582 
583 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
584           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
585           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
586 @*/
587 PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
588 {
589   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
590   PetscMPIInt       rank;
591   PetscInt          tab,intab = ascii->tab;
592   PetscErrorCode    ierr;
593   FILE              *fd = ascii->fd;
594   PetscBool         iascii;
595   int               err;
596 
597   PetscFunctionBegin;
598   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
599   PetscValidCharPointer(format,2);
600   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
601   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
602   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
603   if (rank) PetscFunctionReturn(0);
604 
605   if (ascii->bviewer) { /* pass string up to parent viewer */
606     char        *string;
607     va_list     Argp;
608     size_t      fullLength;
609 
610     ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
611     va_start(Argp,format);
612     ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr);
613     va_end(Argp);
614     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
615     ierr = PetscFree(string);CHKERRQ(ierr);
616   } else { /* write directly to file */
617     va_list Argp;
618     /* flush my own messages that I may have queued up */
619     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
620     PetscInt    i;
621     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
622       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
623       previous = next;
624       next     = next->next;
625       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
626       ierr     = PetscFree(previous);CHKERRQ(ierr);
627     }
628     ascii->petsc_printfqueue       = 0;
629     ascii->petsc_printfqueuelength = 0;
630     tab = intab;
631     while (tab--) {
632       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
633     }
634 
635     va_start(Argp,format);
636     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
637     err  = fflush(fd);
638     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
639     if (petsc_history) {
640       va_start(Argp,format);
641       tab = intab;
642       while (tab--) {
643         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
644       }
645       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
646       err  = fflush(petsc_history);
647       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
648     }
649     va_end(Argp);
650   }
651   PetscFunctionReturn(0);
652 }
653 
654 /*@C
655      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
656 
657     Collective on PetscViewer
658 
659   Input Parameters:
660 +  viewer - the PetscViewer; either ASCII or binary
661 -  name - the name of the file it should use
662 
663     Level: advanced
664 
665 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
666           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
667 
668 @*/
669 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
670 {
671   PetscErrorCode ierr;
672   char           b[PETSC_MAX_PATH_LEN];
673 
674   PetscFunctionBegin;
675   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
676   PetscValidCharPointer(name,2);
677   ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));CHKERRQ(ierr);
678   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));CHKERRQ(ierr);
679   PetscFunctionReturn(0);
680 }
681 
682 /*@C
683      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
684 
685     Not Collective
686 
687   Input Parameter:
688 .  viewer - the PetscViewer; either ASCII or binary
689 
690   Output Parameter:
691 .  name - the name of the file it is using
692 
693     Level: advanced
694 
695 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
696 
697 @*/
698 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
699 {
700   PetscErrorCode ierr;
701 
702   PetscFunctionBegin;
703   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
704   PetscValidPointer(name,2);
705   ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
706   PetscFunctionReturn(0);
707 }
708 
709 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
710 {
711   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
712 
713   PetscFunctionBegin;
714   *name = vascii->filename;
715   PetscFunctionReturn(0);
716 }
717 
718 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
719 {
720   PetscErrorCode    ierr;
721   size_t            len;
722   char              fname[PETSC_MAX_PATH_LEN],*gz;
723   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
724   PetscBool         isstderr,isstdout;
725   PetscMPIInt       rank;
726 
727   PetscFunctionBegin;
728   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
729   if (!name) PetscFunctionReturn(0);
730   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
731 
732   /* Is this file to be compressed */
733   vascii->storecompressed = PETSC_FALSE;
734 
735   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
736   if (gz) {
737     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
738     if (len == 3) {
739       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");
740       *gz = 0;
741       vascii->storecompressed = PETSC_TRUE;
742     }
743   }
744   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
745   if (!rank) {
746     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
747     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
748     /* empty filename means stdout */
749     if (name[0] == 0)  isstdout = PETSC_TRUE;
750     if (isstderr)      vascii->fd = PETSC_STDERR;
751     else if (isstdout) vascii->fd = PETSC_STDOUT;
752     else {
753 
754 
755       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
756       switch (vascii->mode) {
757       case FILE_MODE_READ:
758         vascii->fd = fopen(fname,"r");
759         break;
760       case FILE_MODE_WRITE:
761         vascii->fd = fopen(fname,"w");
762         break;
763       case FILE_MODE_APPEND:
764         vascii->fd = fopen(fname,"a");
765         break;
766       case FILE_MODE_UPDATE:
767         vascii->fd = fopen(fname,"r+");
768         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
769         break;
770       case FILE_MODE_APPEND_UPDATE:
771         /* I really want a file which is opened at the end for updating,
772            not a+, which opens at the beginning, but makes writes at the end.
773         */
774         vascii->fd = fopen(fname,"r+");
775         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
776         else {
777           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
778         }
779         break;
780       default:
781         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
782       }
783       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
784     }
785   }
786 #if defined(PETSC_USE_LOG)
787   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
788 #endif
789   PetscFunctionReturn(0);
790 }
791 
792 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
793 {
794   PetscMPIInt       rank;
795   PetscErrorCode    ierr;
796   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
797 
798   PetscFunctionBegin;
799   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
800   ierr         = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
801   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
802   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
803   ierr         = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
804   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
805   ovascii->fd  = vascii->fd;
806   ovascii->tab = vascii->tab;
807   ovascii->closefile = PETSC_FALSE;
808 
809   vascii->sviewer = *outviewer;
810 
811   (*outviewer)->format  = viewer->format;
812 
813   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
814   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
815   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
816   PetscFunctionReturn(0);
817 }
818 
819 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
820 {
821   PetscErrorCode    ierr;
822   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
823 
824   PetscFunctionBegin;
825   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
826   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
827 
828   ascii->sviewer             = 0;
829   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
830   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
831   PetscFunctionReturn(0);
832 }
833 
834 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
835 {
836   PetscErrorCode    ierr;
837   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
838 
839   PetscFunctionBegin;
840   if (ascii->filename) {
841     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
842   }
843   PetscFunctionReturn(0);
844 }
845 
846 /*MC
847    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
848 
849 
850 .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
851            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
852            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
853 
854   Level: beginner
855 
856 M*/
857 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
858 {
859   PetscViewer_ASCII *vascii;
860   PetscErrorCode    ierr;
861 
862   PetscFunctionBegin;
863   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
864   viewer->data = (void*)vascii;
865 
866   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
867   viewer->ops->flush            = PetscViewerFlush_ASCII;
868   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
869   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
870   viewer->ops->view             = PetscViewerView_ASCII;
871   viewer->ops->read             = PetscViewerASCIIRead;
872 
873   /* defaults to stdout unless set with PetscViewerFileSetName() */
874   vascii->fd        = PETSC_STDOUT;
875   vascii->mode      = FILE_MODE_WRITE;
876   vascii->bviewer   = 0;
877   vascii->subviewer = 0;
878   vascii->sviewer   = 0;
879   vascii->tab       = 0;
880   vascii->tab_store = 0;
881   vascii->filename  = 0;
882   vascii->closefile = PETSC_TRUE;
883 
884   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
885   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
886   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
887   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
888   PetscFunctionReturn(0);
889 }
890 
891 /*@C
892     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
893     several processors.  Output of the first processor is followed by that of the
894     second, etc.
895 
896     Not Collective, must call collective PetscViewerFlush() to get the results out
897 
898     Input Parameters:
899 +   viewer - the ASCII PetscViewer
900 -   format - the usual printf() format string
901 
902     Level: intermediate
903 
904     Notes:
905     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
906     Then you can do multiple independent calls to this routine.
907     The actual synchronized print is then done using PetscViewerFlush().
908     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
909     to conclude the "synchronized session".
910     So the typical calling sequence looks like
911 $ PetscViewerASCIIPushSynchronized(viewer);
912 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
913 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
914 $ ...
915 $ PetscViewerFlush(viewer);
916 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
917 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
918 $ ...
919 $ PetscViewerFlush(viewer);
920 $ PetscViewerASCIIPopSynchronized(viewer);
921 
922     Fortran Note:
923       Can only print a single character* string
924 
925 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
926           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
927           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
928 @*/
929 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
930 {
931   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
932   PetscErrorCode    ierr;
933   PetscMPIInt       rank;
934   PetscInt          tab = vascii->tab;
935   MPI_Comm          comm;
936   FILE              *fp;
937   PetscBool         iascii,hasbviewer = PETSC_FALSE;
938   int               err;
939 
940   PetscFunctionBegin;
941   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
942   PetscValidCharPointer(format,2);
943   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
944   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
945   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
946 
947   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
948   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
949 
950   if (vascii->bviewer) {
951     hasbviewer = PETSC_TRUE;
952     if (!rank) {
953       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
954       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
955       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
956     }
957   }
958 
959   fp   = vascii->fd;
960 
961   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
962     va_list Argp;
963     /* flush my own messages that I may have queued up */
964     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
965     PetscInt    i;
966     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
967       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
968       previous = next;
969       next     = next->next;
970       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
971       ierr     = PetscFree(previous);CHKERRQ(ierr);
972     }
973     vascii->petsc_printfqueue       = 0;
974     vascii->petsc_printfqueuelength = 0;
975 
976     while (tab--) {
977       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
978     }
979 
980     va_start(Argp,format);
981     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
982     err  = fflush(fp);
983     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
984     if (petsc_history) {
985       va_start(Argp,format);
986       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
987       err  = fflush(petsc_history);
988       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
989     }
990     va_end(Argp);
991   } else { /* other processors add to queue */
992     char        *string;
993     va_list     Argp;
994     size_t      fullLength;
995     PrintfQueue next;
996 
997     ierr = PetscNew(&next);CHKERRQ(ierr);
998     if (vascii->petsc_printfqueue) {
999       vascii->petsc_printfqueue->next = next;
1000       vascii->petsc_printfqueue       = next;
1001     } else {
1002       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
1003     }
1004     vascii->petsc_printfqueuelength++;
1005     next->size = QUEUESTRINGSIZE;
1006     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
1007     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
1008     string     = next->string;
1009     tab       *= 2;
1010     while (tab--) {
1011       *string++ = ' ';
1012     }
1013     va_start(Argp,format);
1014     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
1015     va_end(Argp);
1016     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
1017       ierr       = PetscFree(next->string);CHKERRQ(ierr);
1018       next->size = fullLength + 2*vascii->tab;
1019       ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
1020       ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
1021       string     = next->string;
1022       tab        = 2*vascii->tab;
1023       while (tab--) {
1024         *string++ = ' ';
1025       }
1026       va_start(Argp,format);
1027       ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr);
1028       va_end(Argp);
1029     }
1030   }
1031   PetscFunctionReturn(0);
1032 }
1033 
1034 /*@C
1035    PetscViewerASCIIRead - Reads from a ASCII file
1036 
1037    Only process 0 in the PetscViewer may call this
1038 
1039    Input Parameters:
1040 +  viewer - the ascii viewer
1041 .  data - location to write the data
1042 .  num - number of items of data to read
1043 -  datatype - type of data to read
1044 
1045    Output Parameters:
1046 .  count - number of items of data actually read, or NULL
1047 
1048    Level: beginner
1049 
1050    Concepts: ascii files
1051 
1052 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1053           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1054           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1055 @*/
1056 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1057 {
1058   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1059   FILE              *fd = vascii->fd;
1060   PetscInt           i;
1061   int                ret = 0;
1062   PetscMPIInt        rank;
1063   PetscErrorCode     ierr;
1064 
1065   PetscFunctionBegin;
1066   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1067   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1068   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1069   for (i=0; i<num; i++) {
1070     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1071     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1072     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1073     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1074     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1075     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1076     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1077     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1078 #if defined(PETSC_USE_REAL___FLOAT128)
1079     else if (dtype == PETSC___FLOAT128) {
1080       double tmp;
1081       ret = fscanf(fd, "%lg", &tmp);
1082       ((__float128*)data)[i] = tmp;
1083     }
1084 #endif
1085     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1086     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1087     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1088   }
1089   if (count) *count = i;
1090   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1091   PetscFunctionReturn(0);
1092 }
1093 
1094