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
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: PetscBool flg;
17: int err;
20: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
21: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
22: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
23: if (vascii->fd && vascii->closefile) {
24: err = fclose(vascii->fd);
25: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
26: }
27: if (vascii->storecompressed) {
28: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
29: FILE *fp;
30: PetscStrcpy(par,"gzip ");
31: PetscStrcat(par,vascii->filename);
32: #if defined(PETSC_HAVE_POPEN)
33: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
34: if (fgets(buf,1024,fp)) {
35: SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
36: }
37: PetscPClose(PETSC_COMM_SELF,fp);
38: #else
39: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
40: #endif
41: }
42: }
43: PetscFree(vascii->filename);
44: PetscFree(vascii);
46: /* remove the viewer from the list in the MPI Communicator */
47: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
48: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
49: }
51: MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
52: if (flg) {
53: if (vlink && vlink->viewer == viewer) {
54: MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
55: PetscFree(vlink);
56: } else {
57: while (vlink && vlink->next) {
58: if (vlink->next->viewer == viewer) {
59: PetscViewerLink *nv = vlink->next;
60: vlink->next = vlink->next->next;
61: PetscFree(nv);
62: }
63: vlink = vlink->next;
64: }
65: }
66: }
67: return(0);
68: }
72: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
73: {
74: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
75: PetscErrorCode ierr;
77: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
78: return(0);
79: }
83: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
84: {
85: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
86: PetscErrorCode ierr;
88: PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
89: return(0);
90: }
94: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
95: {
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
97: int err;
100: err = fflush(vascii->fd);
101: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
102: return(0);
103: }
107: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
108: {
109: PetscMPIInt rank;
110: PetscErrorCode ierr;
111: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
112: int err;
115: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
116: /* fflush() fails on OSX for read-only descriptors */
117: if (!rank && (vascii->mode != FILE_MODE_READ)) {
118: err = fflush(vascii->fd);
119: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
120: }
122: if (vascii->allowsynchronized) {
123: /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */
124: PetscSynchronizedFlush(((PetscObject)viewer)->comm);
125: }
126: return(0);
127: }
131: /*@C
132: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
134: Not Collective
136: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
137: - fd - file pointer
139: Level: intermediate
141: Fortran Note:
142: This routine is not supported in Fortran.
144: Concepts: PetscViewer^file pointer
145: Concepts: file pointer^getting from PetscViewer
147: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
148: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
149: @*/
150: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
151: {
152: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
155: *fd = vascii->fd;
156: return(0);
157: }
162: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
163: {
164: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
167: *mode = vascii->mode;
168: return(0);
169: }
172: /*@C
173: PetscViewerFileSetMode - Sets the mode in which to open the file.
175: Not Collective
177: + viewer - viewer context, obtained from PetscViewerCreate()
178: - mode - The file mode
180: Level: intermediate
182: Fortran Note:
183: This routine is not supported in Fortran.
185: .keywords: Viewer, file, get, pointer
187: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
188: @*/
193: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
194: {
195: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
198: vascii->mode = mode;
199: return(0);
200: }
203: /*
204: If petsc_history is on, then all Petsc*Printf() results are saved
205: if the appropriate (usually .petschistory) file.
206: */
211: /*@
212: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
214: Not Collective, but only first processor in set has any effect
216: Input Parameters:
217: + viewer - optained with PetscViewerASCIIOpen()
218: - tabs - number of tabs
220: Level: developer
222: Fortran Note:
223: This routine is not supported in Fortran.
225: Concepts: PetscViewerASCII^formating
226: Concepts: tab^setting
228: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
229: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
230: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
231: @*/
232: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
233: {
234: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
235: PetscBool iascii;
236: PetscErrorCode ierr;
240: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
241: if (iascii) {
242: ascii->tab = tabs;
243: }
244: return(0);
245: }
249: /*@
250: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
252: Not Collective, but only first processor in set has any effect
254: Input Parameters:
255: + viewer - optained with PetscViewerASCIIOpen()
256: - tabs - number of tabs
258: Level: developer
260: Fortran Note:
261: This routine is not supported in Fortran.
263: Concepts: PetscViewerASCII^formating
264: Concepts: tab^setting
266: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
267: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
268: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
269: @*/
270: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
271: {
272: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
273: PetscBool iascii;
274: PetscErrorCode ierr;
278: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
279: if (iascii) {
280: ascii->tab += tabs;
281: }
282: return(0);
283: }
287: /*@
288: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
290: Not Collective, but only first processor in set has any effect
292: Input Parameters:
293: + viewer - optained with PetscViewerASCIIOpen()
294: - tabs - number of tabs
296: Level: developer
298: Fortran Note:
299: This routine is not supported in Fortran.
301: Concepts: PetscViewerASCII^formating
302: Concepts: tab^setting
304: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
305: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
306: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
307: @*/
308: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
309: {
310: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
311: PetscBool iascii;
312: PetscErrorCode ierr;
316: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
317: if (iascii) {
318: ascii->tab -= tabs;
319: }
320: return(0);
321: }
325: /*@C
326: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
328: Collective on PetscViewer
330: Input Parameters:
331: + viewer - optained with PetscViewerASCIIOpen()
332: - allow - PETSC_TRUE to allow the synchronized printing
334: Level: intermediate
336: Concepts: PetscViewerASCII^formating
337: Concepts: tab^setting
339: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
340: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
341: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
342: @*/
343: PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
344: {
345: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
346: PetscBool iascii;
347: PetscErrorCode ierr;
351: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
352: if (iascii) {
353: ascii->allowsynchronized = allow;
354: }
355: return(0);
356: }
360: /*@
361: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
362: lines are tabbed.
364: Not Collective, but only first processor in set has any effect
366: Input Parameters:
367: . viewer - optained with PetscViewerASCIIOpen()
369: Level: developer
371: Fortran Note:
372: This routine is not supported in Fortran.
374: Concepts: PetscViewerASCII^formating
375: Concepts: tab^setting
377: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
378: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
379: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
380: @*/
381: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
382: {
383: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
384: PetscBool iascii;
385: PetscErrorCode ierr;
389: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
390: if (iascii) {
391: ascii->tab++;
392: }
393: return(0);
394: }
398: /*@
399: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
400: lines are tabbed.
402: Not Collective, but only first processor in set has any effect
404: Input Parameters:
405: . viewer - optained with PetscViewerASCIIOpen()
407: Level: developer
409: Fortran Note:
410: This routine is not supported in Fortran.
412: Concepts: PetscViewerASCII^formating
413: Concepts: tab^setting
415: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
416: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
417: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
418: @*/
419: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
420: {
421: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
422: PetscErrorCode ierr;
423: PetscBool iascii;
427: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
428: if (iascii) {
429: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
430: ascii->tab--;
431: }
432: return(0);
433: }
437: /*@
438: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
440: Not Collective, but only first processor in set has any effect
442: Input Parameters:
443: + viewer - optained with PetscViewerASCIIOpen()
444: - flg - PETSC_TRUE or PETSC_FALSE
446: Level: developer
448: Fortran Note:
449: This routine is not supported in Fortran.
451: Concepts: PetscViewerASCII^formating
452: Concepts: tab^setting
454: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
455: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
456: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
457: @*/
458: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
459: {
460: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
461: PetscBool iascii;
462: PetscErrorCode ierr;
466: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
467: if (iascii) {
468: if (flg) {
469: ascii->tab = ascii->tab_store;
470: } else {
471: ascii->tab_store = ascii->tab;
472: ascii->tab = 0;
473: }
474: }
475: return(0);
476: }
478: /* ----------------------------------------------------------------------- */
480: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
484: /*@C
485: PetscViewerASCIIPrintf - Prints to a file, only from the first
486: processor in the PetscViewer
488: Not Collective, but only first processor in set has any effect
490: Input Parameters:
491: + viewer - optained with PetscViewerASCIIOpen()
492: - format - the usual printf() format string
494: Level: developer
496: Fortran Note:
497: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
498: That is, you can only pass a single character string from Fortran.
500: Concepts: PetscViewerASCII^printing
501: Concepts: printing^to file
502: Concepts: printf
504: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
505: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
506: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
507: @*/
508: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
509: {
510: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
511: PetscMPIInt rank;
512: PetscInt tab;
513: PetscErrorCode ierr;
514: FILE *fd = ascii->fd;
515: PetscBool iascii;
516: int err;
521: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
522: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
524: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
525: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
526: if (!rank) {
527: va_list Argp;
528: if (ascii->bviewer) {
529: queuefile = fd;
530: }
532: tab = ascii->tab;
533: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
535: va_start(Argp,format);
536: PetscVFPrintf(fd,format,Argp);
537: err = fflush(fd);
538: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
539: if (petsc_history) {
540: va_start(Argp,format);
541: tab = ascii->tab;
542: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
543: (*PetscVFPrintf)(petsc_history,format,Argp);
544: err = fflush(petsc_history);
545: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
546: }
547: va_end(Argp);
548: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
549: va_list Argp;
550: size_t fullLength;
551: char *string;
553: PrintfQueue next;
554: PetscNew(struct _PrintfQueue,&next);
555: if (queue) {queue->next = next; queue = next;}
556: else {queuebase = queue = next;}
557: queuelength++;
558: next->size = QUEUESTRINGSIZE;
559: PetscMalloc(next->size*sizeof(char), &next->string);
560: PetscMemzero(next->string,next->size);
561: string = next->string;
562: tab = 2*ascii->tab;
563: while (tab--) {*string++ = ' ';}
564: va_start(Argp,format);
565: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
566: va_end(Argp);
567: }
568: return(0);
569: }
573: /*@C
574: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
576: Collective on PetscViewer
578: Input Parameters:
579: + viewer - the PetscViewer; either ASCII or binary
580: - name - the name of the file it should use
582: Level: advanced
584: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
585: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
587: @*/
588: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
589: {
595: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
596: return(0);
597: }
601: /*@C
602: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
604: Not Collective
606: Input Parameter:
607: . viewer - the PetscViewer; either ASCII or binary
609: Output Parameter:
610: . name - the name of the file it is using
612: Level: advanced
614: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
616: @*/
617: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
618: {
623: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
624: return(0);
625: }
630: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
631: {
632: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
635: *name = vascii->filename;
636: return(0);
637: }
644: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
645: {
646: PetscErrorCode ierr;
647: size_t len;
648: char fname[PETSC_MAX_PATH_LEN],*gz;
649: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
650: PetscBool isstderr,isstdout;
651: PetscMPIInt rank;
654: if (!name) return(0);
655: PetscFree(vascii->filename);
656: PetscStrallocpy(name,&vascii->filename);
658: /* Is this file to be compressed */
659: vascii->storecompressed = PETSC_FALSE;
660: PetscStrstr(vascii->filename,".gz",&gz);
661: if (gz) {
662: PetscStrlen(gz,&len);
663: if (len == 3) {
664: *gz = 0;
665: vascii->storecompressed = PETSC_TRUE;
666: }
667: }
668: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
669: if (!rank) {
670: PetscStrcmp(name,"stderr",&isstderr);
671: PetscStrcmp(name,"stdout",&isstdout);
672: /* empty filename means stdout */
673: if (name[0] == 0) isstdout = PETSC_TRUE;
674: if (isstderr) vascii->fd = PETSC_STDERR;
675: else if (isstdout) vascii->fd = PETSC_STDOUT;
676: else {
679: PetscFixFilename(name,fname);
680: switch(vascii->mode) {
681: case FILE_MODE_READ:
682: vascii->fd = fopen(fname,"r");
683: break;
684: case FILE_MODE_WRITE:
685: vascii->fd = fopen(fname,"w");
686: break;
687: case FILE_MODE_APPEND:
688: vascii->fd = fopen(fname,"a");
689: break;
690: case FILE_MODE_UPDATE:
691: vascii->fd = fopen(fname,"r+");
692: if (!vascii->fd) {
693: vascii->fd = fopen(fname,"w+");
694: }
695: break;
696: case FILE_MODE_APPEND_UPDATE:
697: /* I really want a file which is opened at the end for updating,
698: not a+, which opens at the beginning, but makes writes at the end.
699: */
700: vascii->fd = fopen(fname,"r+");
701: if (!vascii->fd) {
702: vascii->fd = fopen(fname,"w+");
703: } else {
704: fseek(vascii->fd, 0, SEEK_END);
705: }
706: break;
707: default:
708: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
709: }
710: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
711: }
712: }
713: #if defined(PETSC_USE_LOG)
714: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
715: #endif
716: return(0);
717: }
722: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
723: {
724: PetscMPIInt rank;
725: PetscErrorCode ierr;
726: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
727: const char *name;
730: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
731: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
732: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
733: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
734: ovascii->fd = vascii->fd;
735: ovascii->tab = vascii->tab;
737: vascii->sviewer = *outviewer;
739: (*outviewer)->format = viewer->format;
740: (*outviewer)->iformat = viewer->iformat;
742: PetscObjectGetName((PetscObject)viewer,&name);
743: PetscObjectSetName((PetscObject)(*outviewer),name);
745: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
746: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
747: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
748: if (rank) {
749: (*outviewer)->ops->flush = 0;
750: } else {
751: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
752: }
753: return(0);
754: }
758: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
759: {
760: PetscErrorCode ierr;
761: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
762: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
765: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
766: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
768: ascii->sviewer = 0;
769: vascii->fd = PETSC_STDOUT;
770: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
771: PetscViewerDestroy(outviewer);
772: PetscViewerFlush(viewer);
773: return(0);
774: }
778: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
779: {
780: PetscMPIInt rank;
781: PetscErrorCode ierr;
782: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
783: const char *name;
786: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
787: /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
788: PetscViewerCreate(subcomm,outviewer);
789: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
790: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
791: ovascii->fd = vascii->fd;
792: ovascii->tab = vascii->tab;
794: vascii->sviewer = *outviewer;
796: (*outviewer)->format = viewer->format;
797: (*outviewer)->iformat = viewer->iformat;
799: PetscObjectGetName((PetscObject)viewer,&name);
800: PetscObjectSetName((PetscObject)(*outviewer),name);
802: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
803: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
804: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
805: /* following might not be correct??? */
806: if (rank) {
807: (*outviewer)->ops->flush = 0;
808: } else {
809: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
810: }
811: return(0);
812: }
816: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
817: {
818: PetscErrorCode ierr;
819: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
820: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
823: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
824: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
826: ascii->sviewer = 0;
827: vascii->fd = PETSC_STDOUT;
828: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
829: PetscViewerDestroy(outviewer);
830: PetscViewerFlush(viewer);
831: return(0);
832: }
837: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
838: {
839: PetscViewer_ASCII *vascii;
840: PetscErrorCode ierr;
843: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
844: viewer->data = (void*)vascii;
846: viewer->ops->destroy = PetscViewerDestroy_ASCII;
847: viewer->ops->flush = PetscViewerFlush_ASCII;
848: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
849: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
850: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
851: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
853: /* defaults to stdout unless set with PetscViewerFileSetName() */
854: vascii->fd = PETSC_STDOUT;
855: vascii->mode = FILE_MODE_WRITE;
856: vascii->bviewer = 0;
857: vascii->sviewer = 0;
858: viewer->format = PETSC_VIEWER_DEFAULT;
859: viewer->iformat = 0;
860: vascii->tab = 0;
861: vascii->tab_store = 0;
862: vascii->filename = 0;
863: vascii->closefile = PETSC_TRUE;
865: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
866: PetscViewerFileSetName_ASCII);
867: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
868: PetscViewerFileGetName_ASCII);
869: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
870: PetscViewerFileGetMode_ASCII);
871: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
872: PetscViewerFileSetMode_ASCII);
874: return(0);
875: }
881: /*@C
882: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
883: several processors. Output of the first processor is followed by that of the
884: second, etc.
886: Not Collective, must call collective PetscViewerFlush() to get the results out
888: Input Parameters:
889: + viewer - the ASCII PetscViewer
890: - format - the usual printf() format string
892: Level: intermediate
894: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
896: Fortran Note:
897: Can only print a single character* string
899: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
900: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
901: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
903: @*/
904: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
905: {
906: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
907: PetscErrorCode ierr;
908: PetscMPIInt rank,size;
909: PetscInt tab = vascii->tab;
910: MPI_Comm comm;
911: FILE *fp;
912: PetscBool iascii;
913: int err;
918: PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
919: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
920: MPI_Comm_size(((PetscObject)viewer)->comm,&size);
921: if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
923: comm = ((PetscObject)viewer)->comm;
924: fp = vascii->fd;
925: MPI_Comm_rank(comm,&rank);
926: if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
927:
929: /* First processor prints immediately to fp */
930: if (!rank) {
931: va_list Argp;
933: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
935: va_start(Argp,format);
936: (*PetscVFPrintf)(fp,format,Argp);
937: err = fflush(fp);
938: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
939: queuefile = fp;
940: if (petsc_history) {
941: va_start(Argp,format);
942: (*PetscVFPrintf)(petsc_history,format,Argp);
943: err = fflush(petsc_history);
944: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
945: }
946: va_end(Argp);
947: } else { /* other processors add to local queue */
948: char *string;
949: va_list Argp;
950: size_t fullLength;
951: PrintfQueue next;
953: PetscNew(struct _PrintfQueue,&next);
954: if (queue) {queue->next = next; queue = next;}
955: else {queuebase = queue = next;}
956: queuelength++;
957: next->size = QUEUESTRINGSIZE;
958: PetscMalloc(next->size*sizeof(char), &next->string);
959: PetscMemzero(next->string,next->size);
960: string = next->string;
961: tab *= 2;
962: while (tab--) {*string++ = ' ';}
963: va_start(Argp,format);
964: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
965: va_end(Argp);
966: }
967: return(0);
968: }