Actual source code: filev.c
1: #define PETSC_DLL
3: #include ../src/sys/viewer/impls/ascii/asciiimpl.h
4: #include <stdarg.h>
6: #define QUEUESTRINGSIZE 8192
8: /* ----------------------------------------------------------------------*/
11: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
12: {
13: PetscMPIInt rank;
14: PetscErrorCode ierr;
15: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
16: PetscViewerLink *vlink;
17: PetscTruth flg;
18: int err;
21: if (vascii->sviewer) {
22: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
23: }
24: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
25: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
26: if (vascii->fd) {
27: err = fclose(vascii->fd);
28: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
29: }
30: if (vascii->storecompressed) {
31: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
32: FILE *fp;
33: PetscStrcpy(par,"gzip ");
34: PetscStrcat(par,vascii->filename);
35: #if defined(PETSC_HAVE_POPEN)
36: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
37: if (fgets(buf,1024,fp)) {
38: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
39: }
40: PetscPClose(PETSC_COMM_SELF,fp);
41: #else
42: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
43: #endif
44: }
45: }
46: PetscStrfree(vascii->filename);
47: PetscFree(vascii);
49: /* remove the viewer from the list in the MPI Communicator */
50: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
51: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
52: }
54: MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
55: if (flg) {
56: if (vlink && vlink->viewer == viewer) {
57: MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
58: PetscFree(vlink);
59: } else {
60: while (vlink && vlink->next) {
61: if (vlink->next->viewer == viewer) {
62: PetscViewerLink *nv = vlink->next;
63: vlink->next = vlink->next->next;
64: PetscFree(nv);
65: }
66: vlink = vlink->next;
67: }
68: }
69: }
70: return(0);
71: }
75: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
76: {
77: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
78: PetscErrorCode ierr;
80: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
81: return(0);
82: }
86: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
87: {
88: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
89: PetscErrorCode ierr;
91: PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
92: return(0);
93: }
97: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
98: {
99: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
100: int err;
103: err = fflush(vascii->fd);
104: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
105: return(0);
106: }
110: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
111: {
112: PetscMPIInt rank;
113: PetscErrorCode ierr;
114: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
115: int err;
118: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
119: if (!rank) {
120: err = fflush(vascii->fd);
121: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() call failed");
122: }
124: /*
125: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
126: */
127: PetscSynchronizedFlush(((PetscObject)viewer)->comm);
128: return(0);
129: }
133: /*@C
134: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
136: Not Collective
138: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
139: - fd - file pointer
141: Level: intermediate
143: Fortran Note:
144: This routine is not supported in Fortran.
146: Concepts: PetscViewer^file pointer
147: Concepts: file pointer^getting from PetscViewer
149: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
150: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
151: @*/
152: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
153: {
154: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
157: *fd = vascii->fd;
158: return(0);
159: }
164: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
165: {
166: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
169: *mode = vascii->mode;
170: return(0);
171: }
174: /*@C
175: PetscViewerFileSetMode - Sets the mode in which to open the file.
177: Not Collective
179: + viewer - viewer context, obtained from PetscViewerCreate()
180: - mode - The file mode
182: Level: intermediate
184: Fortran Note:
185: This routine is not supported in Fortran.
187: .keywords: Viewer, file, get, pointer
189: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
190: @*/
195: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
196: {
197: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
200: vascii->mode = mode;
201: return(0);
202: }
205: /*
206: If petsc_history is on, then all Petsc*Printf() results are saved
207: if the appropriate (usually .petschistory) file.
208: */
213: /*@
214: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
216: Not Collective, but only first processor in set has any effect
218: Input Parameters:
219: + viewer - optained with PetscViewerASCIIOpen()
220: - tabs - number of tabs
222: Level: developer
224: Fortran Note:
225: This routine is not supported in Fortran.
227: Concepts: PetscViewerASCII^formating
228: Concepts: tab^setting
230: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
231: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
232: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
233: @*/
234: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
235: {
236: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
237: PetscTruth iascii;
238: PetscErrorCode ierr;
242: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
243: if (iascii) {
244: ascii->tab = tabs;
245: }
246: return(0);
247: }
251: /*@
252: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
253: lines are tabbed.
255: Not Collective, but only first processor in set has any effect
257: Input Parameters:
258: . viewer - optained with PetscViewerASCIIOpen()
260: Level: developer
262: Fortran Note:
263: This routine is not supported in Fortran.
265: Concepts: PetscViewerASCII^formating
266: Concepts: tab^setting
268: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
269: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
270: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
271: @*/
272: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
273: {
274: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
275: PetscTruth iascii;
276: PetscErrorCode ierr;
280: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
281: if (iascii) {
282: ascii->tab++;
283: }
284: return(0);
285: }
289: /*@
290: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
291: lines are tabbed.
293: Not Collective, but only first processor in set has any effect
295: Input Parameters:
296: . viewer - optained with PetscViewerASCIIOpen()
298: Level: developer
300: Fortran Note:
301: This routine is not supported in Fortran.
303: Concepts: PetscViewerASCII^formating
304: Concepts: tab^setting
306: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
307: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
308: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
309: @*/
310: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
311: {
312: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
313: PetscErrorCode ierr;
314: PetscTruth iascii;
318: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
319: if (iascii) {
320: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
321: ascii->tab--;
322: }
323: return(0);
324: }
328: /*@
329: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
331: Not Collective, but only first processor in set has any effect
333: Input Parameters:
334: + viewer - optained with PetscViewerASCIIOpen()
335: - flg - PETSC_YES or PETSC_NO
337: Level: developer
339: Fortran Note:
340: This routine is not supported in Fortran.
342: Concepts: PetscViewerASCII^formating
343: Concepts: tab^setting
345: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
346: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
347: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
348: @*/
349: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
350: {
351: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
352: PetscTruth iascii;
353: PetscErrorCode ierr;
357: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
358: if (iascii) {
359: if (flg) {
360: ascii->tab = ascii->tab_store;
361: } else {
362: ascii->tab_store = ascii->tab;
363: ascii->tab = 0;
364: }
365: }
366: return(0);
367: }
369: /* ----------------------------------------------------------------------- */
371: #include ../src/sys/fileio/mprint.h
375: /*@C
376: PetscViewerASCIIPrintf - Prints to a file, only from the first
377: processor in the PetscViewer
379: Not Collective, but only first processor in set has any effect
381: Input Parameters:
382: + viewer - optained with PetscViewerASCIIOpen()
383: - format - the usual printf() format string
385: Level: developer
387: Fortran Note:
388: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
389: That is, you can only pass a single character string from Fortran.
391: Concepts: PetscViewerASCII^printing
392: Concepts: printing^to file
393: Concepts: printf
395: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
396: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
397: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
398: @*/
399: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
400: {
401: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
402: PetscMPIInt rank;
403: PetscInt tab;
404: PetscErrorCode ierr;
405: FILE *fd = ascii->fd;
406: PetscTruth iascii;
407: int err;
412: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
413: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
415: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
416: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
417: if (!rank) {
418: va_list Argp;
419: if (ascii->bviewer) {
420: queuefile = fd;
421: }
423: tab = ascii->tab;
424: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
426: va_start(Argp,format);
427: PetscVFPrintf(fd,format,Argp);
428: err = fflush(fd);
429: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
430: if (petsc_history) {
431: tab = ascii->tab;
432: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
433: (*PetscVFPrintf)(petsc_history,format,Argp);
434: err = fflush(petsc_history);
435: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
436: }
437: va_end(Argp);
438: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
439: va_list Argp;
440: int fullLength;
441: char *string;
443: PrintfQueue next;
444: PetscNew(struct _PrintfQueue,&next);
445: if (queue) {queue->next = next; queue = next;}
446: else {queuebase = queue = next;}
447: queuelength++;
448: next->size = QUEUESTRINGSIZE;
449: PetscMalloc(next->size*sizeof(char), &next->string);
450: PetscMemzero(next->string,next->size);
451: string = next->string;
452: tab = 2*ascii->tab;
453: while (tab--) {*string++ = ' ';}
454: va_start(Argp,format);
455: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
456: va_end(Argp);
457: }
458: return(0);
459: }
463: /*@C
464: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
466: Collective on PetscViewer
468: Input Parameters:
469: + viewer - the PetscViewer; either ASCII or binary
470: - name - the name of the file it should use
472: Level: advanced
474: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
475: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
477: @*/
478: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
479: {
480: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
485: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
486: if (f) {
487: (*f)(viewer,name);
488: }
489: return(0);
490: }
494: /*@C
495: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
497: Not Collective
499: Input Parameter:
500: . viewer - the PetscViewer; either ASCII or binary
502: Output Parameter:
503: . name - the name of the file it is using
505: Level: advanced
507: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
509: @*/
510: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,char **name)
511: {
512: PetscErrorCode ierr,(*f)(PetscViewer,char **);
516: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
517: if (f) {
518: (*f)(viewer,name);
519: }
520: return(0);
521: }
526: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
527: {
528: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
531: *name = vascii->filename;
532: return(0);
533: }
540: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
541: {
542: PetscErrorCode ierr;
543: size_t len;
544: char fname[PETSC_MAX_PATH_LEN],*gz;
545: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
546: PetscTruth isstderr,isstdout;
547: PetscMPIInt rank;
550: if (!name) return(0);
551: PetscStrfree(vascii->filename);
552: PetscStrallocpy(name,&vascii->filename);
554: /* Is this file to be compressed */
555: vascii->storecompressed = PETSC_FALSE;
556: PetscStrstr(vascii->filename,".gz",&gz);
557: if (gz) {
558: PetscStrlen(gz,&len);
559: if (len == 3) {
560: *gz = 0;
561: vascii->storecompressed = PETSC_TRUE;
562: }
563: }
564: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
565: if (!rank) {
566: PetscStrcmp(name,"stderr",&isstderr);
567: PetscStrcmp(name,"stdout",&isstdout);
568: /* empty filename means stdout */
569: if (name[0] == 0) isstdout = PETSC_TRUE;
570: if (isstderr) vascii->fd = PETSC_STDERR;
571: else if (isstdout) vascii->fd = PETSC_STDOUT;
572: else {
575: PetscFixFilename(name,fname);
576: switch(vascii->mode) {
577: case FILE_MODE_READ:
578: vascii->fd = fopen(fname,"r");
579: break;
580: case FILE_MODE_WRITE:
581: vascii->fd = fopen(fname,"w");
582: break;
583: case FILE_MODE_APPEND:
584: vascii->fd = fopen(fname,"a");
585: break;
586: case FILE_MODE_UPDATE:
587: vascii->fd = fopen(fname,"r+");
588: if (!vascii->fd) {
589: vascii->fd = fopen(fname,"w+");
590: }
591: break;
592: case FILE_MODE_APPEND_UPDATE:
593: /* I really want a file which is opened at the end for updating,
594: not a+, which opens at the beginning, but makes writes at the end.
595: */
596: vascii->fd = fopen(fname,"r+");
597: if (!vascii->fd) {
598: vascii->fd = fopen(fname,"w+");
599: } else {
600: fseek(vascii->fd, 0, SEEK_END);
601: }
602: break;
603: default:
604: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
605: }
606: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
607: }
608: }
609: #if defined(PETSC_USE_LOG)
610: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
611: #endif
612: return(0);
613: }
618: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
619: {
620: PetscMPIInt rank;
621: PetscErrorCode ierr;
622: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
623: const char *name;
626: if (vascii->sviewer) {
627: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
628: }
629: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
630: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
631: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
632: ovascii->fd = vascii->fd;
633: ovascii->tab = vascii->tab;
635: vascii->sviewer = *outviewer;
637: (*outviewer)->format = viewer->format;
638: (*outviewer)->iformat = viewer->iformat;
640: PetscObjectGetName((PetscObject)viewer,&name);
641: PetscObjectSetName((PetscObject)(*outviewer),name);
643: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
644: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
645: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
646: if (rank) {
647: (*outviewer)->ops->flush = 0;
648: } else {
649: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
650: }
651: return(0);
652: }
656: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
657: {
658: PetscErrorCode ierr;
659: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
660: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
663: if (!ascii->sviewer) {
664: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
665: }
666: if (ascii->sviewer != *outviewer) {
667: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
668: }
670: ascii->sviewer = 0;
671: vascii->fd = PETSC_STDOUT;
672: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
673: PetscViewerDestroy(*outviewer);
674: PetscViewerFlush(viewer);
675: return(0);
676: }
680: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
681: {
682: PetscMPIInt rank;
683: PetscErrorCode ierr;
684: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
685: const char *name;
688: if (vascii->sviewer) {
689: SETERRQ(PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
690: }
691: /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
692: PetscViewerCreate(subcomm,outviewer);
693: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
694: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
695: ovascii->fd = vascii->fd;
696: ovascii->tab = vascii->tab;
698: vascii->sviewer = *outviewer;
700: (*outviewer)->format = viewer->format;
701: (*outviewer)->iformat = viewer->iformat;
703: PetscObjectGetName((PetscObject)viewer,&name);
704: PetscObjectSetName((PetscObject)(*outviewer),name);
706: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
707: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
708: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
709: /* following might not be correct??? */
710: if (rank) {
711: (*outviewer)->ops->flush = 0;
712: } else {
713: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
714: }
715: return(0);
716: }
720: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
721: {
722: PetscErrorCode ierr;
723: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
724: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
727: if (!ascii->sviewer) {
728: SETERRQ(PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
729: }
730: if (ascii->sviewer != *outviewer) {
731: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
732: }
734: ascii->sviewer = 0;
735: vascii->fd = PETSC_STDOUT;
736: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
737: PetscViewerDestroy(*outviewer);
738: PetscViewerFlush(viewer);
739: return(0);
740: }
745: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
746: {
747: PetscViewer_ASCII *vascii;
748: PetscErrorCode ierr;
751: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
752: viewer->data = (void*)vascii;
754: viewer->ops->destroy = PetscViewerDestroy_ASCII;
755: viewer->ops->flush = PetscViewerFlush_ASCII;
756: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
757: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
758: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
759: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
761: /* defaults to stdout unless set with PetscViewerFileSetName() */
762: vascii->fd = PETSC_STDOUT;
763: vascii->mode = FILE_MODE_WRITE;
764: vascii->bviewer = 0;
765: vascii->sviewer = 0;
766: viewer->format = PETSC_VIEWER_DEFAULT;
767: viewer->iformat = 0;
768: vascii->tab = 0;
769: vascii->tab_store = 0;
770: vascii->filename = 0;
772: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
773: PetscViewerFileSetName_ASCII);
774: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
775: PetscViewerFileGetName_ASCII);
776: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
777: PetscViewerFileGetMode_ASCII);
778: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
779: PetscViewerFileSetMode_ASCII);
781: return(0);
782: }
788: /*@C
789: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
790: several processors. Output of the first processor is followed by that of the
791: second, etc.
793: Not Collective, must call collective PetscViewerFlush() to get the results out
795: Input Parameters:
796: + viewer - the ASCII PetscViewer
797: - format - the usual printf() format string
799: Level: intermediate
801: Fortran Note:
802: Can only print a single character* string
804: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
805: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
806: PetscViewerASCIIPrintf()
808: @*/
809: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
810: {
811: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
812: PetscErrorCode ierr;
813: PetscMPIInt rank;
814: PetscInt tab = vascii->tab;
815: MPI_Comm comm;
816: FILE *fp;
817: PetscTruth iascii;
818: int err;
823: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
824: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
826: comm = ((PetscObject)viewer)->comm;
827: fp = vascii->fd;
828: MPI_Comm_rank(comm,&rank);
829: if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
830:
832: /* First processor prints immediately to fp */
833: if (!rank) {
834: va_list Argp;
836: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
838: va_start(Argp,format);
839: (*PetscVFPrintf)(fp,format,Argp);
840: err = fflush(fp);
841: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
842: queuefile = fp;
843: if (petsc_history) {
844: (*PetscVFPrintf)(petsc_history,format,Argp);
845: err = fflush(petsc_history);
846: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
847: }
848: va_end(Argp);
849: } else { /* other processors add to local queue */
850: char *string;
851: va_list Argp;
852: int fullLength;
853: PrintfQueue next;
855: PetscNew(struct _PrintfQueue,&next);
856: if (queue) {queue->next = next; queue = next;}
857: else {queuebase = queue = next;}
858: queuelength++;
859: next->size = QUEUESTRINGSIZE;
860: PetscMalloc(next->size*sizeof(char), &next->string);
861: PetscMemzero(next->string,next->size);
862: string = next->string;
863: tab *= 2;
864: while (tab--) {*string++ = ' ';}
865: va_start(Argp,format);
866: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
867: va_end(Argp);
868: }
869: return(0);
870: }
875: /*@C
876: PetscViewerASCIIMonitorCreate - Opens an ASCII file as a monitor object, suitable for the default KSP, SNES and TS monitors
878: Collective on MPI_Comm
880: Input Parameters:
881: + comm - the communicator
882: . name - the file name
883: - tabs - how far in the text should be tabbed
885: Output Parameter:
886: . lab - the context to be used with KSP/SNES/TSMonitorSet()
888: Level: advanced
890: Notes:
891: This can be destroyed with PetscViewerASCIIMonitorDestroy().
893: See PetscViewerASCIIOpen()
895: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorDestroy()
897: @*/
898: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
899: {
903: PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
904: PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
905: (*ctx)->tabs = tabs;
906: return(0);
907: }
911: /*@C
912: PetscViewerASCIIMonitorDestroys - removes a monitor context.
914: Collective on PetscViewerASCIIMonitor
916: Input Parameters:
917: . ctx - the monitor context created with PetscViewerASCIIMonitorCreate()
919: Level: advanced
921: Notes:
922: This is rarely called by users, it is usually called when the KSP, SNES or TS object is destroyed
924: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate()
926: @*/
927: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
928: {
932: PetscViewerDestroy(ctx->viewer);
933: PetscFree(ctx);
934: return(0);
935: }
939: /*@C
940: PetscViewerASCIIMonitorPrintf - Prints to the viewer associated with this monitor context
942: Not Collective, but only first processor in set has any effect
944: Input Parameters:
945: + ctx - the context obtained with PetscViewerASCIIMonitorCreate()
946: - format - the usual printf() format string
948: Level: developer
950: Developer Notes: This code is virtually identical to PetscViewerASCIIPrintf(), however the code
951: could not simply be called from here due to the var args.
953: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
954: PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()
957: @*/
958: PetscErrorCode PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
959: {
960: PetscViewer viewer = ctx->viewer;
961: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
962: PetscMPIInt rank;
963: PetscInt tab;
964: PetscErrorCode ierr;
965: FILE *fd = ascii->fd;
966: PetscTruth iascii;
967: int err;
972: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
973: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
975: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
976: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
977: if (!rank) {
978: va_list Argp;
979: if (ascii->bviewer) {
980: queuefile = fd;
981: }
983: tab = ascii->tab + ctx->tabs;
984: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
986: va_start(Argp,format);
987: (*PetscVFPrintf)(fd,format,Argp);
988: err = fflush(fd);
989: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
990: if (petsc_history) {
991: tab = ascii->tab + ctx->tabs;
992: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
993: (*PetscVFPrintf)(petsc_history,format,Argp);
994: err = fflush(petsc_history);
995: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
996: }
997: va_end(Argp);
998: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
999: va_list Argp;
1000: int fullLength;
1001: char *string;
1002: PrintfQueue next;
1004: PetscNew(struct _PrintfQueue,&next);
1005: if (queue) {queue->next = next; queue = next;}
1006: else {queuebase = queue = next;}
1007: queuelength++;
1008: next->size = QUEUESTRINGSIZE;
1009: PetscMalloc(next->size*sizeof(char), &next->string);
1010: PetscMemzero(next->string,next->size);
1011: string = next->string;
1012: tab = 2*(ascii->tab + ctx->tabs);
1013: while (tab--) {*string++ = ' ';}
1014: va_start(Argp,format);
1015: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
1016: va_end(Argp);
1017: }
1018: return(0);
1019: }