xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 609bdbee21ea3be08735c64dbe00a9ab27759925)
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 /*@
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 /*@
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       *gz = 0;
711       vascii->storecompressed = PETSC_TRUE;
712     }
713   }
714   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
715   if (!rank) {
716     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
717     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
718     /* empty filename means stdout */
719     if (name[0] == 0)  isstdout = PETSC_TRUE;
720     if (isstderr)      vascii->fd = PETSC_STDERR;
721     else if (isstdout) vascii->fd = PETSC_STDOUT;
722     else {
723 
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(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", 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   PetscMPIInt       rank;
765   PetscErrorCode    ierr;
766   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
767 
768   PetscFunctionBegin;
769   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
770   ierr         = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
771   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
772   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
773   ierr         = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
774   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
775   ovascii->fd  = vascii->fd;
776   ovascii->tab = vascii->tab;
777   ovascii->closefile = PETSC_FALSE;
778 
779   vascii->sviewer = *outviewer;
780 
781   (*outviewer)->format  = viewer->format;
782 
783   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
784   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
785   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
786   PetscFunctionReturn(0);
787 }
788 
789 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
790 {
791   PetscErrorCode    ierr;
792   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
793 
794   PetscFunctionBegin;
795   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
796   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
797 
798   ascii->sviewer             = 0;
799   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
800   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
801   PetscFunctionReturn(0);
802 }
803 
804 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
805 {
806   PetscErrorCode    ierr;
807   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
808 
809   PetscFunctionBegin;
810   if (ascii->filename) {
811     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
812   }
813   PetscFunctionReturn(0);
814 }
815 
816 /*MC
817    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
818 
819 
820 .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
821            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
822            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
823 
824   Level: beginner
825 
826 M*/
827 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
828 {
829   PetscViewer_ASCII *vascii;
830   PetscErrorCode    ierr;
831 
832   PetscFunctionBegin;
833   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
834   viewer->data = (void*)vascii;
835 
836   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
837   viewer->ops->flush            = PetscViewerFlush_ASCII;
838   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
839   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
840   viewer->ops->view             = PetscViewerView_ASCII;
841   viewer->ops->read             = PetscViewerASCIIRead;
842 
843   /* defaults to stdout unless set with PetscViewerFileSetName() */
844   vascii->fd        = PETSC_STDOUT;
845   vascii->mode      = FILE_MODE_WRITE;
846   vascii->bviewer   = 0;
847   vascii->subviewer = 0;
848   vascii->sviewer   = 0;
849   vascii->tab       = 0;
850   vascii->tab_store = 0;
851   vascii->filename  = 0;
852   vascii->closefile = PETSC_TRUE;
853 
854   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
855   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
856   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
857   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
858   PetscFunctionReturn(0);
859 }
860 
861 /*@C
862     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
863     several processors.  Output of the first processor is followed by that of the
864     second, etc.
865 
866     Not Collective, must call collective PetscViewerFlush() to get the results out
867 
868     Input Parameters:
869 +   viewer - the ASCII PetscViewer
870 -   format - the usual printf() format string
871 
872     Level: intermediate
873 
874     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
875 
876     Fortran Note:
877       Can only print a single character* string
878 
879 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
880           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
881           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
882 
883 @*/
884 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
885 {
886   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
887   PetscErrorCode    ierr;
888   PetscMPIInt       rank;
889   PetscInt          tab = vascii->tab;
890   MPI_Comm          comm;
891   FILE              *fp;
892   PetscBool         iascii,hasbviewer = PETSC_FALSE;
893   int               err;
894 
895   PetscFunctionBegin;
896   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
897   PetscValidCharPointer(format,2);
898   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
899   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
900   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
901 
902   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
903   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
904 
905   if (vascii->bviewer) {
906     hasbviewer = PETSC_TRUE;
907     if (!rank) {
908       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
909       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
910       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
911     }
912   }
913 
914   fp   = vascii->fd;
915 
916   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
917     va_list Argp;
918     /* flush my own messages that I may have queued up */
919     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
920     PetscInt    i;
921     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
922       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
923       previous = next;
924       next     = next->next;
925       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
926       ierr     = PetscFree(previous);CHKERRQ(ierr);
927     }
928     vascii->petsc_printfqueue       = 0;
929     vascii->petsc_printfqueuelength = 0;
930 
931     while (tab--) {
932       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
933     }
934 
935     va_start(Argp,format);
936     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
937     err  = fflush(fp);
938     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
939     if (petsc_history) {
940       va_start(Argp,format);
941       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
942       err  = fflush(petsc_history);
943       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
944     }
945     va_end(Argp);
946   } else { /* other processors add to queue */
947     char        *string;
948     va_list     Argp;
949     size_t      fullLength;
950     PrintfQueue next;
951 
952     ierr = PetscNew(&next);CHKERRQ(ierr);
953     if (vascii->petsc_printfqueue) {
954       vascii->petsc_printfqueue->next = next;
955       vascii->petsc_printfqueue       = next;
956     } else {
957       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
958     }
959     vascii->petsc_printfqueuelength++;
960     next->size = QUEUESTRINGSIZE;
961     ierr       = PetscMalloc1(next->size, &next->string);CHKERRQ(ierr);
962     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
963     string     = next->string;
964     tab       *= 2;
965     while (tab--) {
966       *string++ = ' ';
967     }
968     va_start(Argp,format);
969     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
970     va_end(Argp);
971   }
972   PetscFunctionReturn(0);
973 }
974 
975 /*@C
976    PetscViewerASCIIRead - Reads from am ASCII file
977 
978    Collective on MPI_Comm
979 
980    Input Parameters:
981 +  viewer - the ascii viewer
982 .  data - location to write the data
983 .  num - number of items of data to read
984 -  datatype - type of data to read
985 
986    Output Parameters:
987 .  count - number of items of data actually read, or NULL
988 
989    Level: beginner
990 
991    Concepts: ascii files
992 
993 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
994           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
995           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
996 @*/
997 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
998 {
999   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1000   FILE              *fd = vascii->fd;
1001   PetscInt           i;
1002   int                ret = 0;
1003 
1004   PetscFunctionBegin;
1005   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1006   for (i=0; i<num; i++) {
1007     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1008     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1009     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1010     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1011     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1012     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1013     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1014     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1015     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1016   }
1017   if (count) *count = i;
1018   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1019   PetscFunctionReturn(0);
1020 }
1021 
1022