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