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