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