Actual source code: filev.c
1: #define PETSC_DLL
3: #include ../src/sys/viewer/impls/ascii/asciiimpl.h
4: #include "petscfix.h"
5: #include <stdarg.h>
7: #define QUEUESTRINGSIZE 8192
9: /* ----------------------------------------------------------------------*/
12: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
13: {
14: PetscMPIInt rank;
15: PetscErrorCode ierr;
16: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
17: PetscViewerLink *vlink;
18: PetscTruth flg;
19: int err;
22: if (vascii->sviewer) {
23: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
24: }
25: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
26: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
27: if (vascii->fd) {
28: err = fclose(vascii->fd);
29: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
30: }
31: if (vascii->storecompressed) {
32: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
33: FILE *fp;
34: PetscStrcpy(par,"gzip ");
35: PetscStrcat(par,vascii->filename);
36: #if defined(PETSC_HAVE_POPEN)
37: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
38: if (fgets(buf,1024,fp)) {
39: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
40: }
41: PetscPClose(PETSC_COMM_SELF,fp);
42: #else
43: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
44: #endif
45: }
46: }
47: PetscStrfree(vascii->filename);
48: PetscFree(vascii);
50: /* remove the viewer from the list in the MPI Communicator */
51: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
52: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
53: }
55: MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
56: if (flg) {
57: if (vlink && vlink->viewer == viewer) {
58: MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
59: PetscFree(vlink);
60: } else {
61: while (vlink && vlink->next) {
62: if (vlink->next->viewer == viewer) {
63: PetscViewerLink *nv = vlink->next;
64: vlink->next = vlink->next->next;
65: PetscFree(nv);
66: }
67: vlink = vlink->next;
68: }
69: }
70: }
71: return(0);
72: }
76: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
77: {
78: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
79: PetscErrorCode ierr;
81: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
82: return(0);
83: }
87: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
88: {
89: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
90: PetscErrorCode ierr;
92: PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
93: return(0);
94: }
98: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
99: {
100: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
101: int err;
104: err = fflush(vascii->fd);
105: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
106: return(0);
107: }
111: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
112: {
113: PetscMPIInt rank;
114: PetscErrorCode ierr;
115: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
116: int err;
119: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
120: if (!rank) {
121: err = fflush(vascii->fd);
122: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() call failed");
123: }
125: /*
126: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
127: */
128: PetscSynchronizedFlush(((PetscObject)viewer)->comm);
129: return(0);
130: }
134: /*@C
135: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
137: Not Collective
139: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
140: - fd - file pointer
142: Level: intermediate
144: Fortran Note:
145: This routine is not supported in Fortran.
147: Concepts: PetscViewer^file pointer
148: Concepts: file pointer^getting from PetscViewer
150: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
151: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
152: @*/
153: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
154: {
155: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
158: *fd = vascii->fd;
159: return(0);
160: }
165: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
166: {
167: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
170: *mode = vascii->mode;
171: return(0);
172: }
175: /*@C
176: PetscViewerFileSetMode - Sets the mode in which to open the file.
178: Not Collective
180: + viewer - viewer context, obtained from PetscViewerCreate()
181: - mode - The file mode
183: Level: intermediate
185: Fortran Note:
186: This routine is not supported in Fortran.
188: .keywords: Viewer, file, get, pointer
190: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
191: @*/
196: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
197: {
198: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
201: vascii->mode = mode;
202: return(0);
203: }
206: /*
207: If petsc_history is on, then all Petsc*Printf() results are saved
208: if the appropriate (usually .petschistory) file.
209: */
214: /*@
215: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
217: Not Collective, but only first processor in set has any effect
219: Input Parameters:
220: + viewer - optained with PetscViewerASCIIOpen()
221: - tabs - number of tabs
223: Level: developer
225: Fortran Note:
226: This routine is not supported in Fortran.
228: Concepts: PetscViewerASCII^formating
229: Concepts: tab^setting
231: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
232: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
233: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
234: @*/
235: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
236: {
237: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
238: PetscTruth iascii;
239: PetscErrorCode ierr;
243: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
244: if (iascii) {
245: ascii->tab = tabs;
246: }
247: return(0);
248: }
252: /*@
253: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
254: lines are tabbed.
256: Not Collective, but only first processor in set has any effect
258: Input Parameters:
259: . viewer - optained with PetscViewerASCIIOpen()
261: Level: developer
263: Fortran Note:
264: This routine is not supported in Fortran.
266: Concepts: PetscViewerASCII^formating
267: Concepts: tab^setting
269: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
270: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
271: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
272: @*/
273: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
274: {
275: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
276: PetscTruth iascii;
277: PetscErrorCode ierr;
281: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
282: if (iascii) {
283: ascii->tab++;
284: }
285: return(0);
286: }
290: /*@
291: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
292: lines are tabbed.
294: Not Collective, but only first processor in set has any effect
296: Input Parameters:
297: . viewer - optained with PetscViewerASCIIOpen()
299: Level: developer
301: Fortran Note:
302: This routine is not supported in Fortran.
304: Concepts: PetscViewerASCII^formating
305: Concepts: tab^setting
307: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
308: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
309: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
310: @*/
311: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
312: {
313: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
314: PetscErrorCode ierr;
315: PetscTruth iascii;
319: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
320: if (iascii) {
321: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
322: ascii->tab--;
323: }
324: return(0);
325: }
329: /*@
330: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
332: Not Collective, but only first processor in set has any effect
334: Input Parameters:
335: + viewer - optained with PetscViewerASCIIOpen()
336: - flg - PETSC_YES or PETSC_NO
338: Level: developer
340: Fortran Note:
341: This routine is not supported in Fortran.
343: Concepts: PetscViewerASCII^formating
344: Concepts: tab^setting
346: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
347: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
348: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
349: @*/
350: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
351: {
352: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
353: PetscTruth iascii;
354: PetscErrorCode ierr;
358: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
359: if (iascii) {
360: if (flg) {
361: ascii->tab = ascii->tab_store;
362: } else {
363: ascii->tab_store = ascii->tab;
364: ascii->tab = 0;
365: }
366: }
367: return(0);
368: }
370: /* ----------------------------------------------------------------------- */
372: #include ../src/sys/fileio/mprint.h
376: /*@C
377: PetscViewerASCIIPrintf - Prints to a file, only from the first
378: processor in the PetscViewer
380: Not Collective, but only first processor in set has any effect
382: Input Parameters:
383: + viewer - optained with PetscViewerASCIIOpen()
384: - format - the usual printf() format string
386: Level: developer
388: Fortran Note:
389: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
390: That is, you can only pass a single character string from Fortran.
392: Concepts: PetscViewerASCII^printing
393: Concepts: printing^to file
394: Concepts: printf
396: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
397: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
398: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
399: @*/
400: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
401: {
402: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
403: PetscMPIInt rank;
404: PetscInt tab;
405: PetscErrorCode ierr;
406: FILE *fd = ascii->fd;
407: PetscTruth iascii;
408: int err;
413: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
414: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
416: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
417: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
418: if (!rank) {
419: va_list Argp;
420: if (ascii->bviewer) {
421: queuefile = fd;
422: }
424: tab = ascii->tab;
425: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
427: va_start(Argp,format);
428: PetscVFPrintf(fd,format,Argp);
429: err = fflush(fd);
430: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
431: if (petsc_history) {
432: tab = ascii->tab;
433: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
434: (*PetscVFPrintf)(petsc_history,format,Argp);
435: err = fflush(petsc_history);
436: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
437: }
438: va_end(Argp);
439: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
440: va_list Argp;
441: int fullLength;
442: char *string;
444: PrintfQueue next;
445: PetscNew(struct _PrintfQueue,&next);
446: if (queue) {queue->next = next; queue = next;}
447: else {queuebase = queue = next;}
448: queuelength++;
449: next->size = QUEUESTRINGSIZE;
450: PetscMalloc(next->size * sizeof(char), &next->string);
451: PetscMemzero(next->string,next->size);
452: string = next->string;
453: tab = 2*ascii->tab;
454: while (tab--) {*string++ = ' ';}
455: va_start(Argp,format);
456: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
457: va_end(Argp);
458: }
459: return(0);
460: }
464: /*@C
465: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
467: Collective on PetscViewer
469: Input Parameters:
470: + viewer - the PetscViewer; either ASCII or binary
471: - name - the name of the file it should use
473: Level: advanced
475: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
476: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
478: @*/
479: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
480: {
481: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
486: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
487: if (f) {
488: (*f)(viewer,name);
489: }
490: return(0);
491: }
495: /*@C
496: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
498: Not Collective
500: Input Parameter:
501: . viewer - the PetscViewer; either ASCII or binary
503: Output Parameter:
504: . name - the name of the file it is using
506: Level: advanced
508: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
510: @*/
511: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,char **name)
512: {
513: PetscErrorCode ierr,(*f)(PetscViewer,char **);
517: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
518: if (f) {
519: (*f)(viewer,name);
520: }
521: return(0);
522: }
527: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
528: {
529: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
532: *name = vascii->filename;
533: return(0);
534: }
541: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
542: {
543: PetscErrorCode ierr;
544: size_t len;
545: char fname[PETSC_MAX_PATH_LEN],*gz;
546: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
547: PetscTruth isstderr,isstdout;
548: PetscMPIInt rank;
551: if (!name) return(0);
552: PetscStrfree(vascii->filename);
553: PetscStrallocpy(name,&vascii->filename);
555: /* Is this file to be compressed */
556: vascii->storecompressed = PETSC_FALSE;
557: PetscStrstr(vascii->filename,".gz",&gz);
558: if (gz) {
559: PetscStrlen(gz,&len);
560: if (len == 3) {
561: *gz = 0;
562: vascii->storecompressed = PETSC_TRUE;
563: }
564: }
565: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
566: if (!rank) {
567: PetscStrcmp(name,"stderr",&isstderr);
568: PetscStrcmp(name,"stdout",&isstdout);
569: /* empty filename means stdout */
570: if (name[0] == 0) isstdout = PETSC_TRUE;
571: if (isstderr) vascii->fd = PETSC_STDERR;
572: else if (isstdout) vascii->fd = PETSC_STDOUT;
573: else {
576: PetscFixFilename(name,fname);
577: switch(vascii->mode) {
578: case FILE_MODE_READ:
579: vascii->fd = fopen(fname,"r");
580: break;
581: case FILE_MODE_WRITE:
582: vascii->fd = fopen(fname,"w");
583: break;
584: case FILE_MODE_APPEND:
585: vascii->fd = fopen(fname,"a");
586: break;
587: case FILE_MODE_UPDATE:
588: vascii->fd = fopen(fname,"r+");
589: if (!vascii->fd) {
590: vascii->fd = fopen(fname,"w+");
591: }
592: break;
593: case FILE_MODE_APPEND_UPDATE:
594: /* I really want a file which is opened at the end for updating,
595: not a+, which opens at the beginning, but makes writes at the end.
596: */
597: vascii->fd = fopen(fname,"r+");
598: if (!vascii->fd) {
599: vascii->fd = fopen(fname,"w+");
600: } else {
601: fseek(vascii->fd, 0, SEEK_END);
602: }
603: break;
604: default:
605: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
606: }
607: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
608: }
609: }
610: #if defined(PETSC_USE_LOG)
611: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
612: #endif
613: return(0);
614: }
619: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
620: {
621: PetscMPIInt rank;
622: PetscErrorCode ierr;
623: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
624: const char *name;
627: if (vascii->sviewer) {
628: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
629: }
630: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
631: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
632: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
633: ovascii->fd = vascii->fd;
634: ovascii->tab = vascii->tab;
636: vascii->sviewer = *outviewer;
638: (*outviewer)->format = viewer->format;
639: (*outviewer)->iformat = viewer->iformat;
641: PetscObjectGetName((PetscObject)viewer,&name);
642: PetscObjectSetName((PetscObject)(*outviewer),name);
644: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
645: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
646: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
647: if (rank) {
648: (*outviewer)->ops->flush = 0;
649: } else {
650: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
651: }
652: return(0);
653: }
657: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
658: {
659: PetscErrorCode ierr;
660: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
661: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
664: if (!ascii->sviewer) {
665: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
666: }
667: if (ascii->sviewer != *outviewer) {
668: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
669: }
671: ascii->sviewer = 0;
672: vascii->fd = PETSC_STDOUT;
673: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
674: PetscViewerDestroy(*outviewer);
675: PetscViewerFlush(viewer);
676: return(0);
677: }
681: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
682: {
683: PetscMPIInt rank;
684: PetscErrorCode ierr;
685: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
686: const char *name;
689: if (vascii->sviewer) {
690: SETERRQ(PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
691: }
692: /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
693: PetscViewerCreate(subcomm,outviewer);
694: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
695: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
696: ovascii->fd = vascii->fd;
697: ovascii->tab = vascii->tab;
699: vascii->sviewer = *outviewer;
701: (*outviewer)->format = viewer->format;
702: (*outviewer)->iformat = viewer->iformat;
704: PetscObjectGetName((PetscObject)viewer,&name);
705: PetscObjectSetName((PetscObject)(*outviewer),name);
707: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
708: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
709: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
710: /* following might not be correct??? */
711: if (rank) {
712: (*outviewer)->ops->flush = 0;
713: } else {
714: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
715: }
716: return(0);
717: }
721: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
722: {
723: PetscErrorCode ierr;
724: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
725: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
728: if (!ascii->sviewer) {
729: SETERRQ(PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
730: }
731: if (ascii->sviewer != *outviewer) {
732: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
733: }
735: ascii->sviewer = 0;
736: vascii->fd = PETSC_STDOUT;
737: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
738: PetscViewerDestroy(*outviewer);
739: PetscViewerFlush(viewer);
740: return(0);
741: }
746: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
747: {
748: PetscViewer_ASCII *vascii;
749: PetscErrorCode ierr;
752: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
753: viewer->data = (void*)vascii;
755: viewer->ops->destroy = PetscViewerDestroy_ASCII;
756: viewer->ops->flush = PetscViewerFlush_ASCII;
757: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
758: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
759: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
760: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
762: /* defaults to stdout unless set with PetscViewerFileSetName() */
763: vascii->fd = PETSC_STDOUT;
764: vascii->mode = FILE_MODE_WRITE;
765: vascii->bviewer = 0;
766: vascii->sviewer = 0;
767: viewer->format = PETSC_VIEWER_DEFAULT;
768: viewer->iformat = 0;
769: vascii->tab = 0;
770: vascii->tab_store = 0;
771: vascii->filename = 0;
773: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
774: PetscViewerFileSetName_ASCII);
775: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
776: PetscViewerFileGetName_ASCII);
777: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
778: PetscViewerFileGetMode_ASCII);
779: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
780: PetscViewerFileSetMode_ASCII);
782: return(0);
783: }
789: /*@C
790: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
791: several processors. Output of the first processor is followed by that of the
792: second, etc.
794: Not Collective, must call collective PetscViewerFlush() to get the results out
796: Input Parameters:
797: + viewer - the ASCII PetscViewer
798: - format - the usual printf() format string
800: Level: intermediate
802: Fortran Note:
803: Can only print a single character* string
805: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
806: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
807: PetscViewerASCIIPrintf()
809: @*/
810: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
811: {
812: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
813: PetscErrorCode ierr;
814: PetscMPIInt rank;
815: PetscInt tab = vascii->tab;
816: MPI_Comm comm;
817: FILE *fp;
818: PetscTruth iascii;
819: int err;
824: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
825: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
827: comm = ((PetscObject)viewer)->comm;
828: fp = vascii->fd;
829: MPI_Comm_rank(comm,&rank);
830: if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
831:
833: /* First processor prints immediately to fp */
834: if (!rank) {
835: va_list Argp;
837: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
839: va_start(Argp,format);
840: (*PetscVFPrintf)(fp,format,Argp);
841: err = fflush(fp);
842: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
843: queuefile = fp;
844: if (petsc_history) {
845: (*PetscVFPrintf)(petsc_history,format,Argp);
846: err = fflush(petsc_history);
847: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
848: }
849: va_end(Argp);
850: } else { /* other processors add to local queue */
851: char *string;
852: va_list Argp;
853: int fullLength;
854: PrintfQueue next;
856: PetscNew(struct _PrintfQueue,&next);
857: if (queue) {queue->next = next; queue = next;}
858: else {queuebase = queue = next;}
859: queuelength++;
860: next->size = QUEUESTRINGSIZE;
861: PetscMalloc(next->size * sizeof(char), &next->string);
862: PetscMemzero(next->string,next->size);
863: string = next->string;
864: tab *= 2;
865: while (tab--) {*string++ = ' ';}
866: va_start(Argp,format);
867: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
868: va_end(Argp);
869: }
870: return(0);
871: }
876: /*@C
877: PetscViewerASCIIMonitorCreate - Opens an ASCII file as a monitor object, suitable for the default KSP, SNES and TS monitors
879: Collective on MPI_Comm
881: Input Parameters:
882: + comm - the communicator
883: . name - the file name
884: - tabs - how far in the text should be tabbed
886: Output Parameter:
887: . lab - the context to be used with KSP/SNES/TSMonitorSet()
889: Level: advanced
891: Notes:
892: This can be destroyed with PetscViewerASCIIMonitorDestroy().
894: See PetscViewerASCIIOpen()
896: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorDestroy()
898: @*/
899: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
900: {
904: PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
905: PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
906: (*ctx)->tabs = tabs;
907: return(0);
908: }
912: /*@C
913: PetscViewerASCIIMonitorDestroys - removes a monitor context.
915: Collective on PetscViewerASCIIMonitor
917: Input Parameters:
918: . ctx - the monitor context created with PetscViewerASCIIMonitorCreate()
920: Level: advanced
922: Notes:
923: This is rarely called by users, it is usually called when the KSP, SNES or TS object is destroyed
925: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate()
927: @*/
928: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
929: {
933: PetscViewerDestroy(ctx->viewer);
934: PetscFree(ctx);
935: return(0);
936: }
940: /*@C
941: PetscViewerASCIIMonitorPrintf - Prints to the viewer associated with this monitor context
943: Not Collective, but only first processor in set has any effect
945: Input Parameters:
946: + ctx - the context obtained with PetscViewerASCIIMonitorCreate()
947: - format - the usual printf() format string
949: Level: developer
951: Developer Notes: This code is virtually identical to PetscViewerASCIIPrintf(), however the code
952: could not simply be called from here due to the var args.
954: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
955: PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()
958: @*/
959: PetscErrorCode PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
960: {
961: PetscViewer viewer = ctx->viewer;
962: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
963: PetscMPIInt rank;
964: PetscInt tab;
965: PetscErrorCode ierr;
966: FILE *fd = ascii->fd;
967: PetscTruth iascii;
968: int err;
973: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
974: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
976: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
977: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
978: if (!rank) {
979: va_list Argp;
980: if (ascii->bviewer) {
981: queuefile = fd;
982: }
984: tab = ascii->tab + ctx->tabs;
985: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
987: va_start(Argp,format);
988: (*PetscVFPrintf)(fd,format,Argp);
989: err = fflush(fd);
990: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
991: if (petsc_history) {
992: tab = ascii->tab + ctx->tabs;
993: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
994: (*PetscVFPrintf)(petsc_history,format,Argp);
995: err = fflush(petsc_history);
996: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
997: }
998: va_end(Argp);
999: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
1000: va_list Argp;
1001: int fullLength;
1002: char *string;
1004: PrintfQueue next;
1005: PetscNew(struct _PrintfQueue,&next);
1006: if (queue) {queue->next = next; queue = next;}
1007: else {queuebase = queue = next;}
1008: queuelength++;
1009: next->size = QUEUESTRINGSIZE;
1010: PetscMalloc(next->size * sizeof(char), &next->string);
1011: PetscMemzero(next->string,next->size);
1012: string = next->string;
1013: tab = 2*(ascii->tab + ctx->tabs);
1014: while (tab--) {*string++ = ' ';}
1015: va_start(Argp,format);
1016: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
1017: va_end(Argp);
1018: }
1019: return(0);
1020: }