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