xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision dcca6d9d80ebd869fe6029bd05a3aa9faafef49e)
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),vascii->fd);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     tab = ascii->tab;
543     while (tab--) {
544       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
545     }
546 
547     va_start(Argp,format);
548     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
549     err  = fflush(fd);
550     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
551     if (petsc_history) {
552       va_start(Argp,format);
553       tab = ascii->tab;
554       while (tab--) {
555         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
556       }
557       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
558       err  = fflush(petsc_history);
559       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
560     }
561     va_end(Argp);
562   }
563   PetscFunctionReturn(0);
564 }
565 
566 #undef __FUNCT__
567 #define __FUNCT__ "PetscViewerFileSetName"
568 /*@C
569      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
570 
571     Collective on PetscViewer
572 
573   Input Parameters:
574 +  viewer - the PetscViewer; either ASCII or binary
575 -  name - the name of the file it should use
576 
577     Level: advanced
578 
579 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
580           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
581 
582 @*/
583 PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
584 {
585   PetscErrorCode ierr;
586 
587   PetscFunctionBegin;
588   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
589   PetscValidCharPointer(name,2);
590   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));CHKERRQ(ierr);
591   PetscFunctionReturn(0);
592 }
593 
594 #undef __FUNCT__
595 #define __FUNCT__ "PetscViewerFileGetName"
596 /*@C
597      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
598 
599     Not Collective
600 
601   Input Parameter:
602 .  viewer - the PetscViewer; either ASCII or binary
603 
604   Output Parameter:
605 .  name - the name of the file it is using
606 
607     Level: advanced
608 
609 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
610 
611 @*/
612 PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
613 {
614   PetscErrorCode ierr;
615 
616   PetscFunctionBegin;
617   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
618   ierr = PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
619   PetscFunctionReturn(0);
620 }
621 
622 #undef __FUNCT__
623 #define __FUNCT__ "PetscViewerFileGetName_ASCII"
624 PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
625 {
626   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
627 
628   PetscFunctionBegin;
629   *name = vascii->filename;
630   PetscFunctionReturn(0);
631 }
632 
633 #undef __FUNCT__
634 #define __FUNCT__ "PetscViewerFileSetName_ASCII"
635 PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
636 {
637   PetscErrorCode    ierr;
638   size_t            len;
639   char              fname[PETSC_MAX_PATH_LEN],*gz;
640   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
641   PetscBool         isstderr,isstdout;
642   PetscMPIInt       rank;
643 
644   PetscFunctionBegin;
645   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
646   if (!name) PetscFunctionReturn(0);
647   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
648 
649   /* Is this file to be compressed */
650   vascii->storecompressed = PETSC_FALSE;
651 
652   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
653   if (gz) {
654     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
655     if (len == 3) {
656       *gz = 0;
657       vascii->storecompressed = PETSC_TRUE;
658     }
659   }
660   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
661   if (!rank) {
662     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
663     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
664     /* empty filename means stdout */
665     if (name[0] == 0)  isstdout = PETSC_TRUE;
666     if (isstderr)      vascii->fd = PETSC_STDERR;
667     else if (isstdout) vascii->fd = PETSC_STDOUT;
668     else {
669 
670 
671       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
672       switch (vascii->mode) {
673       case FILE_MODE_READ:
674         vascii->fd = fopen(fname,"r");
675         break;
676       case FILE_MODE_WRITE:
677         vascii->fd = fopen(fname,"w");
678         break;
679       case FILE_MODE_APPEND:
680         vascii->fd = fopen(fname,"a");
681         break;
682       case FILE_MODE_UPDATE:
683         vascii->fd = fopen(fname,"r+");
684         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
685         break;
686       case FILE_MODE_APPEND_UPDATE:
687         /* I really want a file which is opened at the end for updating,
688            not a+, which opens at the beginning, but makes writes at the end.
689         */
690         vascii->fd = fopen(fname,"r+");
691         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
692         else {
693           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
694         }
695         break;
696       default:
697         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
698       }
699       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
700     }
701   }
702 #if defined(PETSC_USE_LOG)
703   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
704 #endif
705   PetscFunctionReturn(0);
706 }
707 
708 #undef __FUNCT__
709 #define __FUNCT__ "PetscViewerGetSingleton_ASCII"
710 PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
711 {
712   PetscMPIInt       rank;
713   PetscErrorCode    ierr;
714   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
715   const char        *name;
716 
717   PetscFunctionBegin;
718   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
719   ierr         = PetscViewerCreate(PETSC_COMM_SELF,outviewer);CHKERRQ(ierr);
720   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
721   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
722   ovascii->fd  = vascii->fd;
723   ovascii->tab = vascii->tab;
724 
725   vascii->sviewer = *outviewer;
726 
727   (*outviewer)->format  = viewer->format;
728 
729   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
730   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
731 
732   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
733   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
734   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
735   if (rank) (*outviewer)->ops->flush = 0;
736   else      (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
737   PetscFunctionReturn(0);
738 }
739 
740 #undef __FUNCT__
741 #define __FUNCT__ "PetscViewerRestoreSingleton_ASCII"
742 PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
743 {
744   PetscErrorCode    ierr;
745   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
746   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
747 
748   PetscFunctionBegin;
749   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
750   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
751 
752   ascii->sviewer             = 0;
753   vascii->fd                 = PETSC_STDOUT;
754   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
755   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
756   ierr                       = PetscViewerFlush(viewer);CHKERRQ(ierr);
757   PetscFunctionReturn(0);
758 }
759 
760 #undef __FUNCT__
761 #define __FUNCT__ "PetscViewerGetSubcomm_ASCII"
762 PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
763 {
764   PetscErrorCode    ierr;
765   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
766   const char        *name;
767 
768   PetscFunctionBegin;
769   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
770   /* Note that we need to open vascii->filename for the subcomm:
771      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
772      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
773      will return the current viewer, having increfed it.
774    */
775   ierr = PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);CHKERRQ(ierr);
776   if (*outviewer == viewer) PetscFunctionReturn(0);
777   ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
778 
779   ovascii->tab    = vascii->tab;
780   vascii->sviewer = *outviewer;
781 
782   (*outviewer)->format  = viewer->format;
783 
784   ierr = PetscObjectGetName((PetscObject)viewer,&name);CHKERRQ(ierr);
785   ierr = PetscObjectSetName((PetscObject)(*outviewer),name);CHKERRQ(ierr);
786 
787   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
788 
789   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
790   PetscFunctionReturn(0);
791 }
792 
793 #undef __FUNCT__
794 #define __FUNCT__ "PetscViewerRestoreSubcomm_ASCII"
795 PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
796 {
797   PetscErrorCode    ierr;
798   PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
799   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
800 
801   PetscFunctionBegin;
802   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
803   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
804 
805   ascii->sviewer             = 0;
806   oascii->fd                 = PETSC_STDOUT;
807   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
808 
809   ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
810   ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
811   PetscFunctionReturn(0);
812 }
813 
814 #undef __FUNCT__
815 #define __FUNCT__ "PetscViewerView_ASCII"
816 PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
817 {
818   PetscErrorCode    ierr;
819   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
820 
821   PetscFunctionBegin;
822   if (ascii->filename) {
823     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
824   }
825   PetscFunctionReturn(0);
826 }
827 
828 #undef __FUNCT__
829 #define __FUNCT__ "PetscViewerCreate_ASCII"
830 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
831 {
832   PetscViewer_ASCII *vascii;
833   PetscErrorCode    ierr;
834 
835   PetscFunctionBegin;
836   ierr         = PetscNewLog(viewer,PetscViewer_ASCII,&vascii);CHKERRQ(ierr);
837   viewer->data = (void*)vascii;
838 
839   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
840   viewer->ops->flush            = PetscViewerFlush_ASCII;
841   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
842   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
843   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
844   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;
845   viewer->ops->view             = PetscViewerView_ASCII;
846 
847   /* defaults to stdout unless set with PetscViewerFileSetName() */
848   vascii->fd        = PETSC_STDOUT;
849   vascii->mode      = FILE_MODE_WRITE;
850   vascii->bviewer   = 0;
851   vascii->sviewer   = 0;
852   vascii->tab       = 0;
853   vascii->tab_store = 0;
854   vascii->filename  = 0;
855   vascii->closefile = PETSC_TRUE;
856 
857   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
858   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
859   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
860   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
861   PetscFunctionReturn(0);
862 }
863 
864 
865 #undef __FUNCT__
866 #define __FUNCT__ "PetscViewerASCIISynchronizedPrintf"
867 /*@C
868     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
869     several processors.  Output of the first processor is followed by that of the
870     second, etc.
871 
872     Not Collective, must call collective PetscViewerFlush() to get the results out
873 
874     Input Parameters:
875 +   viewer - the ASCII PetscViewer
876 -   format - the usual printf() format string
877 
878     Level: intermediate
879 
880     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
881 
882     Fortran Note:
883       Can only print a single character* string
884 
885 .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
886           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
887           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
888 
889 @*/
890 PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
891 {
892   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
893   PetscErrorCode    ierr;
894   PetscMPIInt       rank,size;
895   PetscInt          tab = vascii->tab;
896   MPI_Comm          comm;
897   FILE              *fp;
898   PetscBool         iascii;
899   int               err;
900 
901   PetscFunctionBegin;
902   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
903   PetscValidCharPointer(format,2);
904   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
905   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
906   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
907   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
908   if (!viewer->ops->flush) PetscFunctionReturn(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
909 
910   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
911   fp   = vascii->fd;
912   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
913 
914   /* First processor prints immediately to fp */
915   if (!rank) {
916     va_list Argp;
917 
918     while (tab--) {
919       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
920     }
921 
922     va_start(Argp,format);
923     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
924     err  = fflush(fp);
925     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
926     if (petsc_history) {
927       va_start(Argp,format);
928       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
929       err  = fflush(petsc_history);
930       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
931     }
932     va_end(Argp);
933   } else { /* other processors add to local queue */
934     char        *string;
935     va_list     Argp;
936     size_t      fullLength;
937     PrintfQueue next;
938 
939     ierr = PetscNew(struct _PrintfQueue,&next);CHKERRQ(ierr);
940     if (petsc_printfqueue) {
941       petsc_printfqueue->next = next;
942       petsc_printfqueue       = next;
943     } else {
944       petsc_printfqueuebase = petsc_printfqueue = next;
945     }
946     petsc_printfqueuelength++;
947     next->size = QUEUESTRINGSIZE;
948     ierr       = PetscMalloc(next->size*sizeof(char), &next->string);CHKERRQ(ierr);
949     ierr       = PetscMemzero(next->string,next->size);CHKERRQ(ierr);
950     string     = next->string;
951     tab       *= 2;
952     while (tab--) {
953       *string++ = ' ';
954     }
955     va_start(Argp,format);
956     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
957     va_end(Argp);
958   }
959   PetscFunctionReturn(0);
960 }
961 
962 
963