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