Actual source code: filev.c
1: #define PETSC_DLL
3: #include src/sys/viewer/impls/ascii/asciiimpl.h
4: #include "petscfix.h"
5: #include <stdarg.h>
7: /* ----------------------------------------------------------------------*/
10: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
11: {
12: PetscMPIInt rank;
13: PetscErrorCode ierr;
14: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
15: PetscViewerLink *vlink;
16: PetscTruth flg;
19: if (vascii->sviewer) {
20: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
21: }
22: MPI_Comm_rank(viewer->comm,&rank);
23: if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
24: if (vascii->fd) fclose(vascii->fd);
25: if (vascii->storecompressed) {
26: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
27: FILE *fp;
28: PetscStrcpy(par,"gzip ");
29: PetscStrcat(par,vascii->filename);
30: #if defined(PETSC_HAVE_POPEN)
31: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
32: if (fgets(buf,1024,fp)) {
33: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
34: }
35: PetscPClose(PETSC_COMM_SELF,fp);
36: #else
37: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
38: #endif
39: }
40: }
41: PetscStrfree(vascii->filename);
42: PetscFree(vascii);
44: /* remove the viewer from the list in the MPI Communicator */
45: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
46: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
47: }
49: MPI_Attr_get(viewer->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
50: if (flg) {
51: if (vlink && vlink->viewer == viewer) {
52: MPI_Attr_put(viewer->comm,Petsc_Viewer_keyval,vlink->next);
53: PetscFree(vlink);
54: } else {
55: while (vlink && vlink->next) {
56: if (vlink->next->viewer == viewer) {
57: PetscViewerLink *nv = vlink->next;
58: vlink->next = vlink->next->next;
59: PetscFree(nv);
60: }
61: vlink = vlink->next;
62: }
63: }
64: }
65: return(0);
66: }
70: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
71: {
72: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
73: PetscErrorCode ierr;
75: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
76: return(0);
77: }
81: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
82: {
83: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
86: fflush(vascii->fd);
87: return(0);
88: }
92: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
93: {
94: PetscMPIInt rank;
95: PetscErrorCode ierr;
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
99: MPI_Comm_rank(viewer->comm,&rank);
100: if (!rank) {
101: fflush(vascii->fd);
102: }
104: /*
105: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
106: */
107: PetscSynchronizedFlush(viewer->comm);
108: return(0);
109: }
113: /*@C
114: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
116: Not Collective
118: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
119: - fd - file pointer
121: Level: intermediate
123: Fortran Note:
124: This routine is not supported in Fortran.
126: Concepts: PetscViewer^file pointer
127: Concepts: file pointer^getting from PetscViewer
129: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
130: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
131: @*/
132: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
133: {
134: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
137: *fd = vascii->fd;
138: return(0);
139: }
144: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
145: {
146: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
149: *mode = vascii->mode;
150: return(0);
151: }
154: /*@C
155: PetscViewerFileSetMode - Sets the mode in which to open the file.
157: Not Collective
159: + viewer - viewer context, obtained from PetscViewerCreate()
160: - mode - The file mode
162: Level: intermediate
164: Fortran Note:
165: This routine is not supported in Fortran.
167: .keywords: Viewer, file, get, pointer
169: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
170: @*/
175: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
176: {
177: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
180: vascii->mode = mode;
181: return(0);
182: }
185: /*
186: If petsc_history is on, then all Petsc*Printf() results are saved
187: if the appropriate (usually .petschistory) file.
188: */
193: /*@
194: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
196: Not Collective, but only first processor in set has any effect
198: Input Parameters:
199: + viewer - optained with PetscViewerASCIIOpen()
200: - tabs - number of tabs
202: Level: developer
204: Fortran Note:
205: This routine is not supported in Fortran.
207: Concepts: PetscViewerASCII^formating
208: Concepts: tab^setting
210: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
211: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
212: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
213: @*/
214: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
215: {
216: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
217: PetscTruth iascii;
218: PetscErrorCode ierr;
222: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
223: if (iascii) {
224: ascii->tab = tabs;
225: }
226: return(0);
227: }
231: /*@
232: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
233: lines are tabbed.
235: Not Collective, but only first processor in set has any effect
237: Input Parameters:
238: . viewer - optained with PetscViewerASCIIOpen()
240: Level: developer
242: Fortran Note:
243: This routine is not supported in Fortran.
245: Concepts: PetscViewerASCII^formating
246: Concepts: tab^setting
248: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
249: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
250: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
251: @*/
252: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
253: {
254: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
255: PetscTruth iascii;
256: PetscErrorCode ierr;
260: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
261: if (iascii) {
262: ascii->tab++;
263: }
264: return(0);
265: }
269: /*@
270: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
271: lines are tabbed.
273: Not Collective, but only first processor in set has any effect
275: Input Parameters:
276: . viewer - optained with PetscViewerASCIIOpen()
278: Level: developer
280: Fortran Note:
281: This routine is not supported in Fortran.
283: Concepts: PetscViewerASCII^formating
284: Concepts: tab^setting
286: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
287: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
288: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
289: @*/
290: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
291: {
292: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
293: PetscErrorCode ierr;
294: PetscTruth iascii;
298: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
299: if (iascii) {
300: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
301: ascii->tab--;
302: }
303: return(0);
304: }
308: /*@
309: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
311: Not Collective, but only first processor in set has any effect
313: Input Parameters:
314: + viewer - optained with PetscViewerASCIIOpen()
315: - flg - PETSC_YES or PETSC_NO
317: Level: developer
319: Fortran Note:
320: This routine is not supported in Fortran.
322: Concepts: PetscViewerASCII^formating
323: Concepts: tab^setting
325: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
326: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
327: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
328: @*/
329: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
330: {
331: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
332: PetscTruth iascii;
333: PetscErrorCode ierr;
337: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
338: if (iascii) {
339: if (flg) {
340: ascii->tab = ascii->tab_store;
341: } else {
342: ascii->tab_store = ascii->tab;
343: ascii->tab = 0;
344: }
345: }
346: return(0);
347: }
349: /* ----------------------------------------------------------------------- */
351: #include src/sys/fileio/mprint.h
355: /*@C
356: PetscViewerASCIIPrintf - Prints to a file, only from the first
357: processor in the PetscViewer
359: Not Collective, but only first processor in set has any effect
361: Input Parameters:
362: + viewer - optained with PetscViewerASCIIOpen()
363: - format - the usual printf() format string
365: Level: developer
367: Fortran Note:
368: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
369: That is, you can only pass a single character string from Fortran.
371: Concepts: PetscViewerASCII^printing
372: Concepts: printing^to file
373: Concepts: printf
375: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
376: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
377: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
378: @*/
379: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
380: {
381: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
382: PetscMPIInt rank;
383: PetscInt tab;
384: PetscErrorCode ierr;
385: FILE *fd = ascii->fd;
386: PetscTruth iascii;
391: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
392: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
394: MPI_Comm_rank(viewer->comm,&rank);
395: if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
396: if (!rank) {
397: va_list Argp;
398: if (ascii->bviewer) {
399: queuefile = fd;
400: }
402: tab = ascii->tab;
403: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
405: va_start(Argp,format);
406: PetscVFPrintf(fd,format,Argp);
407: fflush(fd);
408: if (petsc_history) {
409: tab = ascii->tab;
410: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
411: PetscVFPrintf(petsc_history,format,Argp);
412: fflush(petsc_history);
413: }
414: va_end(Argp);
415: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
416: va_list Argp;
417: char *string;
419: PrintfQueue next;
420: PetscNew(struct _PrintfQueue,&next);
421: if (queue) {queue->next = next; queue = next;}
422: else {queuebase = queue = next;}
423: queuelength++;
424: string = next->string;
425: PetscMemzero(string,QUEUESTRINGSIZE);
426: tab = 2*ascii->tab;
427: while (tab--) {*string++ = ' ';}
428: va_start(Argp,format);
429: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
430: va_end(Argp);
431: }
432: return(0);
433: }
437: /*@C
438: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
440: Collective on PetscViewer
442: Input Parameters:
443: + viewer - the PetscViewer; either ASCII or binary
444: - name - the name of the file it should use
446: Level: advanced
448: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
449: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
451: @*/
452: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
453: {
454: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
459: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
460: if (f) {
461: (*f)(viewer,name);
462: }
463: return(0);
464: }
468: /*@C
469: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
471: Not Collective
473: Input Parameter:
474: . viewer - the PetscViewer; either ASCII or binary
476: Output Parameter:
477: . name - the name of the file it is using
479: Level: advanced
481: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
483: @*/
484: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,char **name)
485: {
486: PetscErrorCode ierr,(*f)(PetscViewer,char **);
490: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
491: if (f) {
492: (*f)(viewer,name);
493: }
494: return(0);
495: }
500: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
501: {
502: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
505: *name = vascii->filename;
506: return(0);
507: }
514: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
515: {
516: PetscErrorCode ierr;
517: size_t len;
518: char fname[PETSC_MAX_PATH_LEN],*gz;
519: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
520: PetscTruth isstderr,isstdout;
521: PetscMPIInt rank;
524: if (!name) return(0);
525: PetscStrallocpy(name,&vascii->filename);
527: /* Is this file to be compressed */
528: vascii->storecompressed = PETSC_FALSE;
529: PetscStrstr(vascii->filename,".gz",&gz);
530: if (gz) {
531: PetscStrlen(gz,&len);
532: if (len == 3) {
533: *gz = 0;
534: vascii->storecompressed = PETSC_TRUE;
535: }
536: }
537: MPI_Comm_rank(viewer->comm,&rank);
538: if (!rank) {
539: PetscStrcmp(name,"stderr",&isstderr);
540: PetscStrcmp(name,"stdout",&isstdout);
541: /* empty filename means stdout */
542: if (name[0] == 0) isstdout = PETSC_TRUE;
543: if (isstderr) vascii->fd = stderr;
544: else if (isstdout) vascii->fd = stdout;
545: else {
548: PetscFixFilename(name,fname);
549: switch(vascii->mode) {
550: case FILE_MODE_READ:
551: vascii->fd = fopen(fname,"r");
552: break;
553: case FILE_MODE_WRITE:
554: vascii->fd = fopen(fname,"w");
555: break;
556: case FILE_MODE_APPEND:
557: vascii->fd = fopen(fname,"a");
558: break;
559: case FILE_MODE_UPDATE:
560: vascii->fd = fopen(fname,"r+");
561: if (!vascii->fd) {
562: vascii->fd = fopen(fname,"w+");
563: }
564: break;
565: case FILE_MODE_APPEND_UPDATE:
566: /* I really want a file which is opened at the end for updating,
567: not a+, which opens at the beginning, but makes writes at the end.
568: */
569: vascii->fd = fopen(fname,"r+");
570: if (!vascii->fd) {
571: vascii->fd = fopen(fname,"w+");
572: } else {
573: fseek(vascii->fd, 0, SEEK_END);
574: }
575: break;
576: default:
577: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
578: }
579: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
580: }
581: }
582: #if defined(PETSC_USE_LOG)
583: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
584: #endif
585: return(0);
586: }
591: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
592: {
593: PetscMPIInt rank;
594: PetscErrorCode ierr;
595: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
596: const char *name;
599: if (vascii->sviewer) {
600: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
601: }
602: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
603: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
604: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
605: ovascii->fd = vascii->fd;
606: ovascii->tab = vascii->tab;
608: vascii->sviewer = *outviewer;
610: (*outviewer)->format = viewer->format;
611: (*outviewer)->iformat = viewer->iformat;
613: PetscObjectGetName((PetscObject)viewer,&name);
614: PetscObjectSetName((PetscObject)(*outviewer),name);
616: MPI_Comm_rank(viewer->comm,&rank);
617: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
618: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
619: if (rank) {
620: (*outviewer)->ops->flush = 0;
621: } else {
622: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
623: }
624: return(0);
625: }
629: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
630: {
631: PetscErrorCode ierr;
632: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
633: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
636: if (!ascii->sviewer) {
637: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
638: }
639: if (ascii->sviewer != *outviewer) {
640: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
641: }
643: ascii->sviewer = 0;
644: vascii->fd = stdout;
645: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
646: PetscViewerDestroy(*outviewer);
647: PetscViewerFlush(viewer);
648: return(0);
649: }
654: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
655: {
656: PetscViewer_ASCII *vascii;
657: PetscErrorCode ierr;
660: PetscNew(PetscViewer_ASCII,&vascii);
661: viewer->data = (void*)vascii;
663: viewer->ops->destroy = PetscViewerDestroy_ASCII;
664: viewer->ops->flush = PetscViewerFlush_ASCII;
665: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
666: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
668: /* defaults to stdout unless set with PetscViewerFileSetName() */
669: vascii->fd = stdout;
670: vascii->mode = FILE_MODE_WRITE;
671: vascii->bviewer = 0;
672: vascii->sviewer = 0;
673: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
674: viewer->iformat = 0;
675: vascii->tab = 0;
676: vascii->tab_store = 0;
677: vascii->filename = 0;
679: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
680: PetscViewerFileSetName_ASCII);
681: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
682: PetscViewerFileGetName_ASCII);
683: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
684: PetscViewerFileGetMode_ASCII);
685: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
686: PetscViewerFileSetMode_ASCII);
688: return(0);
689: }
695: /*@C
696: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
697: several processors. Output of the first processor is followed by that of the
698: second, etc.
700: Not Collective, must call collective PetscViewerFlush() to get the results out
702: Input Parameters:
703: + viewer - the ASCII PetscViewer
704: - format - the usual printf() format string
706: Level: intermediate
708: Fortran Note:
709: Can only print a single character* string
711: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
712: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
713: PetscViewerASCIIPrintf()
715: @*/
716: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
717: {
718: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
719: PetscErrorCode ierr;
720: PetscMPIInt rank;
721: PetscInt tab = vascii->tab;
722: MPI_Comm comm;
723: FILE *fp;
724: PetscTruth iascii;
729: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
730: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
732: comm = viewer->comm;
733: fp = vascii->fd;
734: MPI_Comm_rank(comm,&rank);
735: if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
736:
738: /* First processor prints immediately to fp */
739: if (!rank) {
740: va_list Argp;
742: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
744: va_start(Argp,format);
745: PetscVFPrintf(fp,format,Argp);
746: fflush(fp);
747: queuefile = fp;
748: if (petsc_history) {
749: PetscVFPrintf(petsc_history,format,Argp);
750: fflush(petsc_history);
751: }
752: va_end(Argp);
753: } else { /* other processors add to local queue */
754: char *string;
755: va_list Argp;
756: PrintfQueue next;
758: PetscNew(struct _PrintfQueue,&next);
759: if (queue) {queue->next = next; queue = next;}
760: else {queuebase = queue = next;}
761: queuelength++;
762: string = next->string;
763: PetscMemzero(string,QUEUESTRINGSIZE);
764: tab *= 2;
765: while (tab--) {*string++ = ' ';}
766: va_start(Argp,format);
767: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
768: va_end(Argp);
769: }
770: return(0);
771: }