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