Actual source code: filev.c
petsc-3.4.5 2014-06-29
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/
4: #define QUEUESTRINGSIZE 8192
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;
16: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
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: PetscStrcpy(par,"gzip ");
26: PetscStrcat(par,vascii->filename);
27: #if defined(PETSC_HAVE_POPEN)
28: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
29: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
30: PetscPClose(PETSC_COMM_SELF,fp,NULL);
31: #else
32: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
33: #endif
34: }
35: }
36: PetscFree(vascii->filename);
37: return(0);
38: }
40: /* ----------------------------------------------------------------------*/
43: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
44: {
45: PetscErrorCode ierr;
46: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
47: PetscViewerLink *vlink;
48: PetscBool flg;
51: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
52: PetscViewerFileClose_ASCII(viewer);
53: PetscFree(vascii);
55: /* remove the viewer from the list in the MPI Communicator */
56: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
57: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
58: }
60: MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
61: if (flg) {
62: if (vlink && vlink->viewer == viewer) {
63: MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
64: PetscFree(vlink);
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: PetscFree(nv);
71: }
72: vlink = vlink->next;
73: }
74: }
75: }
76: return(0);
77: }
81: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
82: {
83: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
84: PetscErrorCode ierr;
87: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
88: return(0);
89: }
93: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
94: {
95: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
96: PetscErrorCode ierr;
99: PetscViewerRestoreSubcomm(vascii->bviewer,PetscObjectComm((PetscObject)viewer),&viewer);
100: return(0);
101: }
105: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
106: {
107: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
108: int err;
111: err = fflush(vascii->fd);
112: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
113: return(0);
114: }
118: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
119: {
120: PetscMPIInt rank;
121: PetscErrorCode ierr;
122: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
123: int err;
126: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
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: }
133: if (vascii->allowsynchronized) {
134: /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */
135: PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer));
136: }
137: return(0);
138: }
142: /*@C
143: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
145: Not Collective
147: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
148: - fd - file pointer
150: Level: intermediate
152: Fortran Note:
153: This routine is not supported in Fortran.
155: Concepts: PetscViewer^file pointer
156: Concepts: file pointer^getting from PetscViewer
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;
166: *fd = vascii->fd;
167: return(0);
168: }
172: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
173: {
174: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
177: *mode = vascii->mode;
178: return(0);
179: }
183: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
184: {
185: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
188: vascii->mode = mode;
189: return(0);
190: }
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;
200: /*@
201: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
203: Not Collective, but only first processor in set has any effect
205: Input Parameters:
206: + viewer - optained with PetscViewerASCIIOpen()
207: - tabs - number of tabs
209: Level: developer
211: Fortran Note:
212: This routine is not supported in Fortran.
214: Concepts: PetscViewerASCII^formating
215: Concepts: tab^setting
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;
229: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
230: if (iascii) ascii->tab = tabs;
231: return(0);
232: }
236: /*@
237: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
239: Not Collective, meaningful on first processor only.
241: Input Parameters:
242: . viewer - optained with PetscViewerASCIIOpen()
243: Output Parameters:
244: . tabs - number of tabs
246: Level: developer
248: Fortran Note:
249: This routine is not supported in Fortran.
251: Concepts: PetscViewerASCII^formating
252: Concepts: tab^retrieval
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;
266: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
267: if (iascii && tabs) *tabs = ascii->tab;
268: return(0);
269: }
273: /*@
274: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
276: Not Collective, but only first processor in set has any effect
278: Input Parameters:
279: + viewer - optained with PetscViewerASCIIOpen()
280: - tabs - number of tabs
282: Level: developer
284: Fortran Note:
285: This routine is not supported in Fortran.
287: Concepts: PetscViewerASCII^formating
288: Concepts: tab^setting
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;
302: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
303: if (iascii) ascii->tab += tabs;
304: return(0);
305: }
309: /*@
310: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
312: Not Collective, but only first processor in set has any effect
314: Input Parameters:
315: + viewer - optained with PetscViewerASCIIOpen()
316: - tabs - number of tabs
318: Level: developer
320: Fortran Note:
321: This routine is not supported in Fortran.
323: Concepts: PetscViewerASCII^formating
324: Concepts: tab^setting
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;
338: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
339: if (iascii) ascii->tab -= tabs;
340: return(0);
341: }
345: /*@C
346: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
348: Collective on PetscViewer
350: Input Parameters:
351: + viewer - optained with PetscViewerASCIIOpen()
352: - allow - PETSC_TRUE to allow the synchronized printing
354: Level: intermediate
356: Concepts: PetscViewerASCII^formating
357: Concepts: tab^setting
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;
371: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
372: if (iascii) ascii->allowsynchronized = allow;
373: return(0);
374: }
378: /*@
379: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
380: lines are tabbed.
382: Not Collective, but only first processor in set has any effect
384: Input Parameters:
385: . viewer - optained with PetscViewerASCIIOpen()
387: Level: developer
389: Fortran Note:
390: This routine is not supported in Fortran.
392: Concepts: PetscViewerASCII^formating
393: Concepts: tab^setting
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;
407: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
408: if (iascii) ascii->tab++;
409: return(0);
410: }
414: /*@
415: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
416: lines are tabbed.
418: Not Collective, but only first processor in set has any effect
420: Input Parameters:
421: . viewer - optained with PetscViewerASCIIOpen()
423: Level: developer
425: Fortran Note:
426: This routine is not supported in Fortran.
428: Concepts: PetscViewerASCII^formating
429: Concepts: tab^setting
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;
443: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
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: return(0);
449: }
453: /*@
454: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
456: Not Collective, but only first processor in set has any effect
458: Input Parameters:
459: + viewer - optained with PetscViewerASCIIOpen()
460: - flg - PETSC_TRUE or PETSC_FALSE
462: Level: developer
464: Fortran Note:
465: This routine is not supported in Fortran.
467: Concepts: PetscViewerASCII^formating
468: Concepts: tab^setting
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;
482: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
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: return(0);
491: }
493: /* ----------------------------------------------------------------------- */
495: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
499: /*@C
500: PetscViewerASCIIPrintf - Prints to a file, only from the first
501: processor in the PetscViewer
503: Not Collective, but only first processor in set has any effect
505: Input Parameters:
506: + viewer - optained with PetscViewerASCIIOpen()
507: - format - the usual printf() format string
509: Level: developer
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.
515: Concepts: PetscViewerASCII^printing
516: Concepts: printing^to file
517: Concepts: printf
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;
536: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
537: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
539: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
540: if (!rank) {
541: va_list Argp;
542: if (ascii->bviewer) petsc_printfqueuefile = fd;
544: tab = ascii->tab;
545: while (tab--) {
546: PetscFPrintf(PETSC_COMM_SELF,fd," ");
547: }
549: va_start(Argp,format);
550: (*PetscVFPrintf)(fd,format,Argp);
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: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
558: }
559: (*PetscVFPrintf)(petsc_history,format,Argp);
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: return(0);
566: }
570: /*@C
571: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
573: Collective on PetscViewer
575: Input Parameters:
576: + viewer - the PetscViewer; either ASCII or binary
577: - name - the name of the file it should use
579: Level: advanced
581: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
582: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
584: @*/
585: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
586: {
592: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
593: return(0);
594: }
598: /*@C
599: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
601: Not Collective
603: Input Parameter:
604: . viewer - the PetscViewer; either ASCII or binary
606: Output Parameter:
607: . name - the name of the file it is using
609: Level: advanced
611: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
613: @*/
614: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
615: {
620: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
621: return(0);
622: }
626: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
627: {
628: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
631: *name = vascii->filename;
632: return(0);
633: }
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;
647: PetscViewerFileClose_ASCII(viewer);
648: if (!name) return(0);
649: PetscStrallocpy(name,&vascii->filename);
651: /* Is this file to be compressed */
652: vascii->storecompressed = PETSC_FALSE;
654: PetscStrstr(vascii->filename,".gz",&gz);
655: if (gz) {
656: PetscStrlen(gz,&len);
657: if (len == 3) {
658: *gz = 0;
659: vascii->storecompressed = PETSC_TRUE;
660: }
661: }
662: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
663: if (!rank) {
664: PetscStrcmp(name,"stderr",&isstderr);
665: PetscStrcmp(name,"stdout",&isstdout);
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 {
673: PetscFixFilename(name,fname);
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: fseek(vascii->fd, 0, SEEK_END);
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: return(0);
708: }
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;
720: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
721: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
722: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
723: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
724: ovascii->fd = vascii->fd;
725: ovascii->tab = vascii->tab;
727: vascii->sviewer = *outviewer;
729: (*outviewer)->format = viewer->format;
731: PetscObjectGetName((PetscObject)viewer,&name);
732: PetscObjectSetName((PetscObject)(*outviewer),name);
734: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
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: return(0);
740: }
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;
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");
754: ascii->sviewer = 0;
755: vascii->fd = PETSC_STDOUT;
756: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
757: PetscViewerDestroy(outviewer);
758: PetscViewerFlush(viewer);
759: return(0);
760: }
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;
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: PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
778: if (*outviewer == viewer) return(0);
779: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
781: ovascii->tab = vascii->tab;
782: vascii->sviewer = *outviewer;
784: (*outviewer)->format = viewer->format;
786: PetscObjectGetName((PetscObject)viewer,&name);
787: PetscObjectSetName((PetscObject)(*outviewer),name);
789: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
791: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
792: return(0);
793: }
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;
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");
807: ascii->sviewer = 0;
808: oascii->fd = PETSC_STDOUT;
809: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
811: PetscViewerDestroy(outviewer);
812: PetscViewerFlush(viewer);
813: return(0);
814: }
818: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
819: {
820: PetscErrorCode ierr;
821: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
824: if (ascii->filename) {
825: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
826: }
827: return(0);
828: }
832: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
833: {
834: PetscViewer_ASCII *vascii;
835: PetscErrorCode ierr;
838: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
839: viewer->data = (void*)vascii;
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;
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;
859: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
860: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
861: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
862: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
863: return(0);
864: }
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.
874: Not Collective, must call collective PetscViewerFlush() to get the results out
876: Input Parameters:
877: + viewer - the ASCII PetscViewer
878: - format - the usual printf() format string
880: Level: intermediate
882: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
884: Fortran Note:
885: Can only print a single character* string
887: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
888: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
889: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
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;
906: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
907: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
908: MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);
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) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
912: PetscObjectGetComm((PetscObject)viewer,&comm);
913: fp = vascii->fd;
914: MPI_Comm_rank(comm,&rank);
916: /* First processor prints immediately to fp */
917: if (!rank) {
918: va_list Argp;
920: while (tab--) {
921: PetscFPrintf(PETSC_COMM_SELF,fp," ");
922: }
924: va_start(Argp,format);
925: (*PetscVFPrintf)(fp,format,Argp);
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: (*PetscVFPrintf)(petsc_history,format,Argp);
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;
942: PetscNew(struct _PrintfQueue,&next);
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: PetscMalloc(next->size*sizeof(char), &next->string);
952: PetscMemzero(next->string,next->size);
953: string = next->string;
954: tab *= 2;
955: while (tab--) {
956: *string++ = ' ';
957: }
958: va_start(Argp,format);
959: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
960: va_end(Argp);
961: }
962: return(0);
963: }