Actual source code: filev.c
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 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(),
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: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253: if (iascii) {
254: ascii->tab = tabs;
255: }
256: return(0);
257: }
261: /*@
262: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
264: Not Collective, but only first processor in set has any effect
266: Input Parameters:
267: + viewer - optained with PetscViewerASCIIOpen()
268: - tabs - number of tabs
270: Level: developer
272: Fortran Note:
273: This routine is not supported in Fortran.
275: Concepts: PetscViewerASCII^formating
276: Concepts: tab^setting
278: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
279: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
280: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
281: @*/
282: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
283: {
284: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
285: PetscBool iascii;
286: PetscErrorCode ierr;
290: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
291: if (iascii) {
292: ascii->tab += tabs;
293: }
294: return(0);
295: }
299: /*@
300: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
302: Not Collective, but only first processor in set has any effect
304: Input Parameters:
305: + viewer - optained with PetscViewerASCIIOpen()
306: - tabs - number of tabs
308: Level: developer
310: Fortran Note:
311: This routine is not supported in Fortran.
313: Concepts: PetscViewerASCII^formating
314: Concepts: tab^setting
316: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
317: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
318: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
319: @*/
320: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
321: {
322: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
323: PetscBool iascii;
324: PetscErrorCode ierr;
328: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
329: if (iascii) {
330: ascii->tab -= tabs;
331: }
332: return(0);
333: }
337: /*@C
338: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
340: Collective on PetscViewer
342: Input Parameters:
343: + viewer - optained with PetscViewerASCIIOpen()
344: - allow - PETSC_TRUE to allow the synchronized printing
346: Level: intermediate
348: Concepts: PetscViewerASCII^formating
349: Concepts: tab^setting
351: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
352: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
353: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
354: @*/
355: PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
356: {
357: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
358: PetscBool iascii;
359: PetscErrorCode ierr;
363: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
364: if (iascii) {
365: ascii->allowsynchronized = allow;
366: }
367: return(0);
368: }
372: /*@
373: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
374: lines are tabbed.
376: Not Collective, but only first processor in set has any effect
378: Input Parameters:
379: . viewer - optained with PetscViewerASCIIOpen()
381: Level: developer
383: Fortran Note:
384: This routine is not supported in Fortran.
386: Concepts: PetscViewerASCII^formating
387: Concepts: tab^setting
389: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
390: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
391: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
392: @*/
393: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
394: {
395: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
396: PetscBool iascii;
397: PetscErrorCode ierr;
401: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
402: if (iascii) {
403: ascii->tab++;
404: }
405: return(0);
406: }
410: /*@
411: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
412: lines are tabbed.
414: Not Collective, but only first processor in set has any effect
416: Input Parameters:
417: . viewer - optained with PetscViewerASCIIOpen()
419: Level: developer
421: Fortran Note:
422: This routine is not supported in Fortran.
424: Concepts: PetscViewerASCII^formating
425: Concepts: tab^setting
427: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
428: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
429: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
430: @*/
431: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
432: {
433: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
434: PetscErrorCode ierr;
435: PetscBool iascii;
439: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
440: if (iascii) {
441: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
442: ascii->tab--;
443: }
444: return(0);
445: }
449: /*@
450: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
452: Not Collective, but only first processor in set has any effect
454: Input Parameters:
455: + viewer - optained with PetscViewerASCIIOpen()
456: - flg - PETSC_TRUE or PETSC_FALSE
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: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
468: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469: @*/
470: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
471: {
472: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473: PetscBool iascii;
474: PetscErrorCode ierr;
478: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
479: if (iascii) {
480: if (flg) {
481: ascii->tab = ascii->tab_store;
482: } else {
483: ascii->tab_store = ascii->tab;
484: ascii->tab = 0;
485: }
486: }
487: return(0);
488: }
490: /* ----------------------------------------------------------------------- */
492: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
496: /*@C
497: PetscViewerASCIIPrintf - Prints to a file, only from the first
498: processor in the PetscViewer
500: Not Collective, but only first processor in set has any effect
502: Input Parameters:
503: + viewer - optained with PetscViewerASCIIOpen()
504: - format - the usual printf() format string
506: Level: developer
508: Fortran Note:
509: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
510: That is, you can only pass a single character string from Fortran.
512: Concepts: PetscViewerASCII^printing
513: Concepts: printing^to file
514: Concepts: printf
516: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
517: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
518: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
519: @*/
520: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
521: {
522: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
523: PetscMPIInt rank;
524: PetscInt tab;
525: PetscErrorCode ierr;
526: FILE *fd = ascii->fd;
527: PetscBool iascii;
528: int err;
533: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
534: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
536: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
537: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
538: if (!rank) {
539: va_list Argp;
540: if (ascii->bviewer) {
541: queuefile = fd;
542: }
544: tab = ascii->tab;
545: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
547: va_start(Argp,format);
548: (*PetscVFPrintf)(fd,format,Argp);
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--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
555: (*PetscVFPrintf)(petsc_history,format,Argp);
556: err = fflush(petsc_history);
557: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
558: }
559: va_end(Argp);
560: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
561: va_list Argp;
562: size_t fullLength;
563: char *string;
565: PrintfQueue next;
566: PetscNew(struct _PrintfQueue,&next);
567: if (queue) {queue->next = next; queue = next;}
568: else {queuebase = queue = next;}
569: queuelength++;
570: next->size = QUEUESTRINGSIZE;
571: PetscMalloc(next->size*sizeof(char), &next->string);
572: PetscMemzero(next->string,next->size);
573: string = next->string;
574: tab = 2*ascii->tab;
575: while (tab--) {*string++ = ' ';}
576: va_start(Argp,format);
577: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
578: va_end(Argp);
579: }
580: return(0);
581: }
585: /*@C
586: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
588: Collective on PetscViewer
590: Input Parameters:
591: + viewer - the PetscViewer; either ASCII or binary
592: - name - the name of the file it should use
594: Level: advanced
596: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
597: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
599: @*/
600: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
601: {
607: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
608: return(0);
609: }
613: /*@C
614: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
616: Not Collective
618: Input Parameter:
619: . viewer - the PetscViewer; either ASCII or binary
621: Output Parameter:
622: . name - the name of the file it is using
624: Level: advanced
626: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
628: @*/
629: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
630: {
635: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
636: return(0);
637: }
639: EXTERN_C_BEGIN
642: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
643: {
644: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
647: *name = vascii->filename;
648: return(0);
649: }
650: EXTERN_C_END
653: EXTERN_C_BEGIN
656: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
657: {
658: PetscErrorCode ierr;
659: size_t len;
660: char fname[PETSC_MAX_PATH_LEN],*gz;
661: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
662: PetscBool isstderr,isstdout;
663: PetscMPIInt rank;
666: PetscViewerFileClose_ASCII(viewer);
667: if (!name) return(0);
668: PetscStrallocpy(name,&vascii->filename);
670: /* Is this file to be compressed */
671: vascii->storecompressed = PETSC_FALSE;
672: PetscStrstr(vascii->filename,".gz",&gz);
673: if (gz) {
674: PetscStrlen(gz,&len);
675: if (len == 3) {
676: *gz = 0;
677: vascii->storecompressed = PETSC_TRUE;
678: }
679: }
680: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
681: if (!rank) {
682: PetscStrcmp(name,"stderr",&isstderr);
683: PetscStrcmp(name,"stdout",&isstdout);
684: /* empty filename means stdout */
685: if (name[0] == 0) isstdout = PETSC_TRUE;
686: if (isstderr) vascii->fd = PETSC_STDERR;
687: else if (isstdout) vascii->fd = PETSC_STDOUT;
688: else {
691: PetscFixFilename(name,fname);
692: switch(vascii->mode) {
693: case FILE_MODE_READ:
694: vascii->fd = fopen(fname,"r");
695: break;
696: case FILE_MODE_WRITE:
697: vascii->fd = fopen(fname,"w");
698: break;
699: case FILE_MODE_APPEND:
700: vascii->fd = fopen(fname,"a");
701: break;
702: case FILE_MODE_UPDATE:
703: vascii->fd = fopen(fname,"r+");
704: if (!vascii->fd) {
705: vascii->fd = fopen(fname,"w+");
706: }
707: break;
708: case FILE_MODE_APPEND_UPDATE:
709: /* I really want a file which is opened at the end for updating,
710: not a+, which opens at the beginning, but makes writes at the end.
711: */
712: vascii->fd = fopen(fname,"r+");
713: if (!vascii->fd) {
714: vascii->fd = fopen(fname,"w+");
715: } else {
716: fseek(vascii->fd, 0, SEEK_END);
717: }
718: break;
719: default:
720: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
721: }
722: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
723: }
724: }
725: #if defined(PETSC_USE_LOG)
726: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
727: #endif
728: return(0);
729: }
730: EXTERN_C_END
734: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
735: {
736: PetscMPIInt rank;
737: PetscErrorCode ierr;
738: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
739: const char *name;
742: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
743: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
744: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
745: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
746: ovascii->fd = vascii->fd;
747: ovascii->tab = vascii->tab;
749: vascii->sviewer = *outviewer;
751: (*outviewer)->format = viewer->format;
752: (*outviewer)->iformat = viewer->iformat;
754: PetscObjectGetName((PetscObject)viewer,&name);
755: PetscObjectSetName((PetscObject)(*outviewer),name);
757: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
758: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
759: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
760: if (rank) {
761: (*outviewer)->ops->flush = 0;
762: } else {
763: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
764: }
765: return(0);
766: }
770: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
771: {
772: PetscErrorCode ierr;
773: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
774: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
777: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
778: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
780: ascii->sviewer = 0;
781: vascii->fd = PETSC_STDOUT;
782: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
783: PetscViewerDestroy(outviewer);
784: PetscViewerFlush(viewer);
785: return(0);
786: }
790: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
791: {
792: PetscMPIInt rank;
793: PetscErrorCode ierr;
794: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
795: const char *name;
798: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
799: PetscViewerCreate(subcomm,outviewer);
800: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
801: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
802: ovascii->fd = vascii->fd;
803: ovascii->tab = vascii->tab;
805: vascii->sviewer = *outviewer;
807: (*outviewer)->format = viewer->format;
808: (*outviewer)->iformat = viewer->iformat;
810: PetscObjectGetName((PetscObject)viewer,&name);
811: PetscObjectSetName((PetscObject)(*outviewer),name);
813: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
814: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
815: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
816: /* following might not be correct??? */
817: if (rank) {
818: (*outviewer)->ops->flush = 0;
819: } else {
820: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
821: }
822: return(0);
823: }
827: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
828: {
829: PetscErrorCode ierr;
830: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
831: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
834: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
835: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
837: ascii->sviewer = 0;
838: vascii->fd = PETSC_STDOUT;
839: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
840: PetscViewerDestroy(outviewer);
841: PetscViewerFlush(viewer);
842: return(0);
843: }
845: EXTERN_C_BEGIN
848: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
849: {
850: PetscViewer_ASCII *vascii;
851: PetscErrorCode ierr;
854: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
855: viewer->data = (void*)vascii;
857: viewer->ops->destroy = PetscViewerDestroy_ASCII;
858: viewer->ops->flush = PetscViewerFlush_ASCII;
859: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
860: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
861: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
862: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
864: /* defaults to stdout unless set with PetscViewerFileSetName() */
865: vascii->fd = PETSC_STDOUT;
866: vascii->mode = FILE_MODE_WRITE;
867: vascii->bviewer = 0;
868: vascii->sviewer = 0;
869: viewer->format = PETSC_VIEWER_DEFAULT;
870: viewer->iformat = 0;
871: vascii->tab = 0;
872: vascii->tab_store = 0;
873: vascii->filename = 0;
874: vascii->closefile = PETSC_TRUE;
876: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
877: PetscViewerFileSetName_ASCII);
878: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
879: PetscViewerFileGetName_ASCII);
880: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
881: PetscViewerFileGetMode_ASCII);
882: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
883: PetscViewerFileSetMode_ASCII);
885: return(0);
886: }
887: EXTERN_C_END
892: /*@C
893: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
894: several processors. Output of the first processor is followed by that of the
895: second, etc.
897: Not Collective, must call collective PetscViewerFlush() to get the results out
899: Input Parameters:
900: + viewer - the ASCII PetscViewer
901: - format - the usual printf() format string
903: Level: intermediate
905: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
907: Fortran Note:
908: Can only print a single character* string
910: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
911: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
912: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
914: @*/
915: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
916: {
917: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
918: PetscErrorCode ierr;
919: PetscMPIInt rank,size;
920: PetscInt tab = vascii->tab;
921: MPI_Comm comm;
922: FILE *fp;
923: PetscBool iascii;
924: int err;
929: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
930: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
931: MPI_Comm_size(((PetscObject)viewer)->comm,&size);
932: if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
933: if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
935: comm = ((PetscObject)viewer)->comm;
936: fp = vascii->fd;
937: MPI_Comm_rank(comm,&rank);
938: if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
939:
941: /* First processor prints immediately to fp */
942: if (!rank) {
943: va_list Argp;
945: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
947: va_start(Argp,format);
948: (*PetscVFPrintf)(fp,format,Argp);
949: err = fflush(fp);
950: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
951: queuefile = fp;
952: if (petsc_history) {
953: va_start(Argp,format);
954: (*PetscVFPrintf)(petsc_history,format,Argp);
955: err = fflush(petsc_history);
956: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
957: }
958: va_end(Argp);
959: } else { /* other processors add to local queue */
960: char *string;
961: va_list Argp;
962: size_t fullLength;
963: PrintfQueue next;
965: PetscNew(struct _PrintfQueue,&next);
966: if (queue) {queue->next = next; queue = next;}
967: else {queuebase = queue = next;}
968: queuelength++;
969: next->size = QUEUESTRINGSIZE;
970: PetscMalloc(next->size*sizeof(char), &next->string);
971: PetscMemzero(next->string,next->size);
972: string = next->string;
973: tab *= 2;
974: while (tab--) {*string++ = ' ';}
975: va_start(Argp,format);
976: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
977: va_end(Argp);
978: }
979: return(0);
980: }