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