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