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