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