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