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