Actual source code: filev.c
petsc-3.3-p7 2013-05-11
2: #include <../src/sys/viewer/impls/ascii/asciiimpl.h> /*I "petscsys.h" I*/
3: #include <stdarg.h>
5: #define QUEUESTRINGSIZE 8192
9: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
10: {
11: PetscErrorCode ierr;
12: PetscMPIInt rank;
13: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
14: int err;
17: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
18: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
19: if (vascii->fd && vascii->closefile) {
20: err = fclose(vascii->fd);
21: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
22: }
23: if (vascii->storecompressed) {
24: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
25: FILE *fp;
26: PetscStrcpy(par,"gzip ");
27: PetscStrcat(par,vascii->filename);
28: #if defined(PETSC_HAVE_POPEN)
29: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
30: if (fgets(buf,1024,fp)) {
31: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
32: }
33: PetscPClose(PETSC_COMM_SELF,fp);
34: #else
35: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
36: #endif
37: }
38: }
39: PetscFree(vascii->filename);
40: return(0);
41: }
43: /* ----------------------------------------------------------------------*/
46: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
47: {
48: PetscErrorCode ierr;
49: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
50: PetscViewerLink *vlink;
51: PetscBool flg;
54: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
55: PetscViewerFileClose_ASCII(viewer);
56: PetscFree(vascii);
58: /* remove the viewer from the list in the MPI Communicator */
59: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
60: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
61: }
63: MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
64: if (flg) {
65: if (vlink && vlink->viewer == viewer) {
66: MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
67: PetscFree(vlink);
68: } else {
69: while (vlink && vlink->next) {
70: if (vlink->next->viewer == viewer) {
71: PetscViewerLink *nv = vlink->next;
72: vlink->next = vlink->next->next;
73: PetscFree(nv);
74: }
75: vlink = vlink->next;
76: }
77: }
78: }
79: return(0);
80: }
84: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
85: {
86: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
87: PetscErrorCode ierr;
89: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
90: return(0);
91: }
95: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
96: {
97: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
98: PetscErrorCode ierr;
100: PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
101: return(0);
102: }
106: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
107: {
108: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
109: int err;
112: err = fflush(vascii->fd);
113: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
114: return(0);
115: }
119: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
120: {
121: PetscMPIInt rank;
122: PetscErrorCode ierr;
123: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
124: int err;
127: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
128: /* fflush() fails on OSX for read-only descriptors */
129: if (!rank && (vascii->mode != FILE_MODE_READ)) {
130: err = fflush(vascii->fd);
131: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
132: }
134: if (vascii->allowsynchronized) {
135: /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */
136: PetscSynchronizedFlush(((PetscObject)viewer)->comm);
137: }
138: return(0);
139: }
143: /*@C
144: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
146: Not Collective
148: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
149: - fd - file pointer
151: Level: intermediate
153: Fortran Note:
154: This routine is not supported in Fortran.
156: Concepts: PetscViewer^file pointer
157: Concepts: file pointer^getting from PetscViewer
159: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
160: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
161: @*/
162: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
163: {
164: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
167: *fd = vascii->fd;
168: return(0);
169: }
171: EXTERN_C_BEGIN
174: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
175: {
176: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
179: *mode = vascii->mode;
180: return(0);
181: }
182: EXTERN_C_END
184: /*@C
185: PetscViewerFileSetMode - Sets the mode in which to open the file.
187: Not Collective
189: + viewer - viewer context, obtained from PetscViewerCreate()
190: - mode - The file mode
192: Level: intermediate
194: Fortran Note:
195: This routine is not supported in Fortran.
197: .keywords: Viewer, file, get, pointer
199: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
200: @*/
202: EXTERN_C_BEGIN
205: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
206: {
207: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
210: vascii->mode = mode;
211: return(0);
212: }
213: EXTERN_C_END
215: /*
216: If petsc_history is on, then all Petsc*Printf() results are saved
217: if the appropriate (usually .petschistory) file.
218: */
219: extern FILE *petsc_history;
223: /*@
224: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
226: Not Collective, but only first processor in set has any effect
228: Input Parameters:
229: + viewer - optained with PetscViewerASCIIOpen()
230: - tabs - number of tabs
232: Level: developer
234: Fortran Note:
235: This routine is not supported in Fortran.
237: Concepts: PetscViewerASCII^formating
238: Concepts: tab^setting
240: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
241: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
242: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
243: @*/
244: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
245: {
246: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
247: PetscBool iascii;
248: PetscErrorCode ierr;
252: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253: if (iascii) {
254: ascii->tab = tabs;
255: }
256: return(0);
257: }
261: /*@
262: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
264: Not Collective, meaningful on first processor only.
266: Input Parameters:
267: . viewer - optained with PetscViewerASCIIOpen()
268: Output Parameters:
269: . tabs - number of tabs
271: Level: developer
273: Fortran Note:
274: This routine is not supported in Fortran.
276: Concepts: PetscViewerASCII^formating
277: Concepts: tab^retrieval
279: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
280: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
281: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
282: @*/
283: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
284: {
285: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
286: PetscBool iascii;
287: PetscErrorCode ierr;
291: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
292: if (iascii && tabs) {
293: *tabs = ascii->tab;
294: }
295: return(0);
296: }
300: /*@
301: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
303: Not Collective, but only first processor in set has any effect
305: Input Parameters:
306: + viewer - optained with PetscViewerASCIIOpen()
307: - tabs - number of tabs
309: Level: developer
311: Fortran Note:
312: This routine is not supported in Fortran.
314: Concepts: PetscViewerASCII^formating
315: Concepts: tab^setting
317: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
318: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
319: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
320: @*/
321: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
322: {
323: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
324: PetscBool iascii;
325: PetscErrorCode ierr;
329: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
330: if (iascii) {
331: ascii->tab += tabs;
332: }
333: return(0);
334: }
338: /*@
339: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
341: Not Collective, but only first processor in set has any effect
343: Input Parameters:
344: + viewer - optained with PetscViewerASCIIOpen()
345: - tabs - number of tabs
347: Level: developer
349: Fortran Note:
350: This routine is not supported in Fortran.
352: Concepts: PetscViewerASCII^formating
353: Concepts: tab^setting
355: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
356: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
357: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
358: @*/
359: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
360: {
361: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
362: PetscBool iascii;
363: PetscErrorCode ierr;
367: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
368: if (iascii) {
369: ascii->tab -= tabs;
370: }
371: return(0);
372: }
376: /*@C
377: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
379: Collective on PetscViewer
381: Input Parameters:
382: + viewer - optained with PetscViewerASCIIOpen()
383: - allow - PETSC_TRUE to allow the synchronized printing
385: Level: intermediate
387: Concepts: PetscViewerASCII^formating
388: Concepts: tab^setting
390: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
391: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
392: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
393: @*/
394: PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
395: {
396: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
397: PetscBool iascii;
398: PetscErrorCode ierr;
402: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
403: if (iascii) {
404: ascii->allowsynchronized = allow;
405: }
406: return(0);
407: }
411: /*@
412: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
413: lines are tabbed.
415: Not Collective, but only first processor in set has any effect
417: Input Parameters:
418: . viewer - optained with PetscViewerASCIIOpen()
420: Level: developer
422: Fortran Note:
423: This routine is not supported in Fortran.
425: Concepts: PetscViewerASCII^formating
426: Concepts: tab^setting
428: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
429: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
430: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
431: @*/
432: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
433: {
434: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
435: PetscBool iascii;
436: PetscErrorCode ierr;
440: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
441: if (iascii) {
442: ascii->tab++;
443: }
444: return(0);
445: }
449: /*@
450: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
451: lines are tabbed.
453: Not Collective, but only first processor in set has any effect
455: Input Parameters:
456: . viewer - optained with PetscViewerASCIIOpen()
458: Level: developer
460: Fortran Note:
461: This routine is not supported in Fortran.
463: Concepts: PetscViewerASCII^formating
464: Concepts: tab^setting
466: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
467: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
468: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469: @*/
470: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
471: {
472: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473: PetscErrorCode ierr;
474: PetscBool iascii;
478: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
479: if (iascii) {
480: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
481: ascii->tab--;
482: }
483: return(0);
484: }
488: /*@
489: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
491: Not Collective, but only first processor in set has any effect
493: Input Parameters:
494: + viewer - optained with PetscViewerASCIIOpen()
495: - flg - PETSC_TRUE or PETSC_FALSE
497: Level: developer
499: Fortran Note:
500: This routine is not supported in Fortran.
502: Concepts: PetscViewerASCII^formating
503: Concepts: tab^setting
505: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
506: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
507: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
508: @*/
509: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
510: {
511: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
512: PetscBool iascii;
513: PetscErrorCode ierr;
517: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
518: if (iascii) {
519: if (flg) {
520: ascii->tab = ascii->tab_store;
521: } else {
522: ascii->tab_store = ascii->tab;
523: ascii->tab = 0;
524: }
525: }
526: return(0);
527: }
529: /* ----------------------------------------------------------------------- */
531: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
535: /*@C
536: PetscViewerASCIIPrintf - Prints to a file, only from the first
537: processor in the PetscViewer
539: Not Collective, but only first processor in set has any effect
541: Input Parameters:
542: + viewer - optained with PetscViewerASCIIOpen()
543: - format - the usual printf() format string
545: Level: developer
547: Fortran Note:
548: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
549: That is, you can only pass a single character string from Fortran.
551: Concepts: PetscViewerASCII^printing
552: Concepts: printing^to file
553: Concepts: printf
555: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
556: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
557: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
558: @*/
559: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
560: {
561: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
562: PetscMPIInt rank;
563: PetscInt tab;
564: PetscErrorCode ierr;
565: FILE *fd = ascii->fd;
566: PetscBool iascii;
567: int err;
572: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
573: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
575: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
576: if (!rank) {
577: va_list Argp;
578: if (ascii->bviewer) {
579: petsc_printfqueuefile = fd;
580: }
582: tab = ascii->tab;
583: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
585: va_start(Argp,format);
586: (*PetscVFPrintf)(fd,format,Argp);
587: err = fflush(fd);
588: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
589: if (petsc_history) {
590: va_start(Argp,format);
591: tab = ascii->tab;
592: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
593: (*PetscVFPrintf)(petsc_history,format,Argp);
594: err = fflush(petsc_history);
595: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
596: }
597: va_end(Argp);
598: }
599: return(0);
600: }
604: /*@C
605: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
607: Collective on PetscViewer
609: Input Parameters:
610: + viewer - the PetscViewer; either ASCII or binary
611: - name - the name of the file it should use
613: Level: advanced
615: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
616: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
618: @*/
619: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
620: {
626: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
627: return(0);
628: }
632: /*@C
633: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
635: Not Collective
637: Input Parameter:
638: . viewer - the PetscViewer; either ASCII or binary
640: Output Parameter:
641: . name - the name of the file it is using
643: Level: advanced
645: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
647: @*/
648: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
649: {
654: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
655: return(0);
656: }
658: EXTERN_C_BEGIN
661: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
662: {
663: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
666: *name = vascii->filename;
667: return(0);
668: }
669: EXTERN_C_END
672: EXTERN_C_BEGIN
675: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
676: {
677: PetscErrorCode ierr;
678: size_t len;
679: char fname[PETSC_MAX_PATH_LEN],*gz;
680: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
681: PetscBool isstderr,isstdout;
682: PetscMPIInt rank;
685: PetscViewerFileClose_ASCII(viewer);
686: if (!name) return(0);
687: PetscStrallocpy(name,&vascii->filename);
689: /* Is this file to be compressed */
690: vascii->storecompressed = PETSC_FALSE;
691: PetscStrstr(vascii->filename,".gz",&gz);
692: if (gz) {
693: PetscStrlen(gz,&len);
694: if (len == 3) {
695: *gz = 0;
696: vascii->storecompressed = PETSC_TRUE;
697: }
698: }
699: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
700: if (!rank) {
701: PetscStrcmp(name,"stderr",&isstderr);
702: PetscStrcmp(name,"stdout",&isstdout);
703: /* empty filename means stdout */
704: if (name[0] == 0) isstdout = PETSC_TRUE;
705: if (isstderr) vascii->fd = PETSC_STDERR;
706: else if (isstdout) vascii->fd = PETSC_STDOUT;
707: else {
710: PetscFixFilename(name,fname);
711: switch(vascii->mode) {
712: case FILE_MODE_READ:
713: vascii->fd = fopen(fname,"r");
714: break;
715: case FILE_MODE_WRITE:
716: vascii->fd = fopen(fname,"w");
717: break;
718: case FILE_MODE_APPEND:
719: vascii->fd = fopen(fname,"a");
720: break;
721: case FILE_MODE_UPDATE:
722: vascii->fd = fopen(fname,"r+");
723: if (!vascii->fd) {
724: vascii->fd = fopen(fname,"w+");
725: }
726: break;
727: case FILE_MODE_APPEND_UPDATE:
728: /* I really want a file which is opened at the end for updating,
729: not a+, which opens at the beginning, but makes writes at the end.
730: */
731: vascii->fd = fopen(fname,"r+");
732: if (!vascii->fd) {
733: vascii->fd = fopen(fname,"w+");
734: } else {
735: fseek(vascii->fd, 0, SEEK_END);
736: }
737: break;
738: default:
739: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
740: }
741: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
742: }
743: }
744: #if defined(PETSC_USE_LOG)
745: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
746: #endif
747: return(0);
748: }
749: EXTERN_C_END
753: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
754: {
755: PetscMPIInt rank;
756: PetscErrorCode ierr;
757: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
758: const char *name;
761: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
762: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
763: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
764: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
765: ovascii->fd = vascii->fd;
766: ovascii->tab = vascii->tab;
768: vascii->sviewer = *outviewer;
770: (*outviewer)->format = viewer->format;
771: (*outviewer)->iformat = viewer->iformat;
773: PetscObjectGetName((PetscObject)viewer,&name);
774: PetscObjectSetName((PetscObject)(*outviewer),name);
776: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
777: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
778: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
779: if (rank) {
780: (*outviewer)->ops->flush = 0;
781: } else {
782: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
783: }
784: return(0);
785: }
789: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
790: {
791: PetscErrorCode ierr;
792: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
793: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
796: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
797: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
799: ascii->sviewer = 0;
800: vascii->fd = PETSC_STDOUT;
801: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
802: PetscViewerDestroy(outviewer);
803: PetscViewerFlush(viewer);
804: return(0);
805: }
809: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
810: {
811: PetscErrorCode ierr;
812: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
813: const char *name;
816: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
817: /* Note that we need to open vascii->filename for the subcomm:
818: we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
819: Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
820: will return the current viewer, having increfed it.
821: */
822: PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
823: if(*outviewer == viewer) return(0);
824: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
826: ovascii->tab = vascii->tab;
827: vascii->sviewer = *outviewer;
829: (*outviewer)->format = viewer->format;
830: (*outviewer)->iformat = viewer->iformat;
832: PetscObjectGetName((PetscObject)viewer,&name);
833: PetscObjectSetName((PetscObject)(*outviewer),name);
835: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
836: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
837: return(0);
838: }
842: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
843: {
844: PetscErrorCode ierr;
845: PetscViewer_ASCII *oascii = (PetscViewer_ASCII *)(*outviewer)->data;
846: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
849: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
850: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
852: ascii->sviewer = 0;
853: oascii->fd = PETSC_STDOUT;
854: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
855: PetscViewerDestroy(outviewer);
856: PetscViewerFlush(viewer);
857: return(0);
858: }
860: EXTERN_C_BEGIN
863: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
864: {
865: PetscViewer_ASCII *vascii;
866: PetscErrorCode ierr;
869: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
870: viewer->data = (void*)vascii;
872: viewer->ops->destroy = PetscViewerDestroy_ASCII;
873: viewer->ops->flush = PetscViewerFlush_ASCII;
874: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
875: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
876: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
877: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
879: /* defaults to stdout unless set with PetscViewerFileSetName() */
880: vascii->fd = PETSC_STDOUT;
881: vascii->mode = FILE_MODE_WRITE;
882: vascii->bviewer = 0;
883: vascii->sviewer = 0;
884: viewer->format = PETSC_VIEWER_DEFAULT;
885: viewer->iformat = 0;
886: vascii->tab = 0;
887: vascii->tab_store = 0;
888: vascii->filename = 0;
889: vascii->closefile = PETSC_TRUE;
891: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
892: PetscViewerFileSetName_ASCII);
893: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
894: PetscViewerFileGetName_ASCII);
895: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
896: PetscViewerFileGetMode_ASCII);
897: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
898: PetscViewerFileSetMode_ASCII);
900: return(0);
901: }
902: EXTERN_C_END
907: /*@C
908: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
909: several processors. Output of the first processor is followed by that of the
910: second, etc.
912: Not Collective, must call collective PetscViewerFlush() to get the results out
914: Input Parameters:
915: + viewer - the ASCII PetscViewer
916: - format - the usual printf() format string
918: Level: intermediate
920: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
922: Fortran Note:
923: Can only print a single character* string
925: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
926: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
927: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
929: @*/
930: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
931: {
932: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
933: PetscErrorCode ierr;
934: PetscMPIInt rank,size;
935: PetscInt tab = vascii->tab;
936: MPI_Comm comm;
937: FILE *fp;
938: PetscBool iascii;
939: int err;
944: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
945: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
946: MPI_Comm_size(((PetscObject)viewer)->comm,&size);
947: if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
948: if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
950: comm = ((PetscObject)viewer)->comm;
951: fp = vascii->fd;
952: MPI_Comm_rank(comm,&rank);
954: /* First processor prints immediately to fp */
955: if (!rank) {
956: va_list Argp;
958: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
960: va_start(Argp,format);
961: (*PetscVFPrintf)(fp,format,Argp);
962: err = fflush(fp);
963: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
964: petsc_printfqueuefile = fp;
965: if (petsc_history) {
966: va_start(Argp,format);
967: (*PetscVFPrintf)(petsc_history,format,Argp);
968: err = fflush(petsc_history);
969: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
970: }
971: va_end(Argp);
972: } else { /* other processors add to local queue */
973: char *string;
974: va_list Argp;
975: size_t fullLength;
976: PrintfQueue next;
978: PetscNew(struct _PrintfQueue,&next);
979: if (petsc_printfqueue) {petsc_printfqueue->next = next; petsc_printfqueue = next;}
980: else {petsc_printfqueuebase = petsc_printfqueue = next;}
981: petsc_printfqueuelength++;
982: next->size = QUEUESTRINGSIZE;
983: PetscMalloc(next->size*sizeof(char), &next->string);
984: PetscMemzero(next->string,next->size);
985: string = next->string;
986: tab *= 2;
987: while (tab--) {*string++ = ' ';}
988: va_start(Argp,format);
989: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
990: va_end(Argp);
991: }
992: return(0);
993: }