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