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: /* ----------------------------------------------------------------------*/
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: PetscTruth flg;
17: int err;
20: if (vascii->sviewer) {
21: SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
22: }
23: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
24: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
25: if (vascii->fd) {
26: err = fclose(vascii->fd);
27: if (err) SETERRQ(PETSC_ERR_SYS,"fclose() failed on file");
28: }
29: if (vascii->storecompressed) {
30: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
31: FILE *fp;
32: PetscStrcpy(par,"gzip ");
33: PetscStrcat(par,vascii->filename);
34: #if defined(PETSC_HAVE_POPEN)
35: PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
36: if (fgets(buf,1024,fp)) {
37: SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
38: }
39: PetscPClose(PETSC_COMM_SELF,fp);
40: #else
41: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
42: #endif
43: }
44: }
45: PetscStrfree(vascii->filename);
46: PetscFree(vascii);
48: /* remove the viewer from the list in the MPI Communicator */
49: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
50: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
51: }
53: MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
54: if (flg) {
55: if (vlink && vlink->viewer == viewer) {
56: MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
57: PetscFree(vlink);
58: } else {
59: while (vlink && vlink->next) {
60: if (vlink->next->viewer == viewer) {
61: PetscViewerLink *nv = vlink->next;
62: vlink->next = vlink->next->next;
63: PetscFree(nv);
64: }
65: vlink = vlink->next;
66: }
67: }
68: }
69: return(0);
70: }
74: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
75: {
76: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
77: PetscErrorCode ierr;
79: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
80: return(0);
81: }
85: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
86: {
87: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
88: PetscErrorCode ierr;
90: PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
91: return(0);
92: }
96: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
97: {
98: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
99: int err;
102: err = fflush(vascii->fd);
103: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
104: return(0);
105: }
109: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
110: {
111: PetscMPIInt rank;
112: PetscErrorCode ierr;
113: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
114: int err;
117: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
118: if (!rank) {
119: err = fflush(vascii->fd);
120: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() call failed");
121: }
123: /*
124: Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
125: */
126: PetscSynchronizedFlush(((PetscObject)viewer)->comm);
127: return(0);
128: }
132: /*@C
133: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
135: Not Collective
137: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
138: - fd - file pointer
140: Level: intermediate
142: Fortran Note:
143: This routine is not supported in Fortran.
145: Concepts: PetscViewer^file pointer
146: Concepts: file pointer^getting from PetscViewer
148: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
149: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
150: @*/
151: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
152: {
153: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
156: *fd = vascii->fd;
157: return(0);
158: }
163: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
164: {
165: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
168: *mode = vascii->mode;
169: return(0);
170: }
173: /*@C
174: PetscViewerFileSetMode - Sets the mode in which to open the file.
176: Not Collective
178: + viewer - viewer context, obtained from PetscViewerCreate()
179: - mode - The file mode
181: Level: intermediate
183: Fortran Note:
184: This routine is not supported in Fortran.
186: .keywords: Viewer, file, get, pointer
188: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
189: @*/
194: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
195: {
196: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
199: vascii->mode = mode;
200: return(0);
201: }
204: /*
205: If petsc_history is on, then all Petsc*Printf() results are saved
206: if the appropriate (usually .petschistory) file.
207: */
212: /*@
213: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
215: Not Collective, but only first processor in set has any effect
217: Input Parameters:
218: + viewer - optained with PetscViewerASCIIOpen()
219: - tabs - number of tabs
221: Level: developer
223: Fortran Note:
224: This routine is not supported in Fortran.
226: Concepts: PetscViewerASCII^formating
227: Concepts: tab^setting
229: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
230: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
231: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
232: @*/
233: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
234: {
235: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
236: PetscTruth iascii;
237: PetscErrorCode ierr;
241: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
242: if (iascii) {
243: ascii->tab = tabs;
244: }
245: return(0);
246: }
250: /*@
251: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
252: lines are tabbed.
254: Not Collective, but only first processor in set has any effect
256: Input Parameters:
257: . viewer - optained with PetscViewerASCIIOpen()
259: Level: developer
261: Fortran Note:
262: This routine is not supported in Fortran.
264: Concepts: PetscViewerASCII^formating
265: Concepts: tab^setting
267: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
268: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
269: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
270: @*/
271: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
272: {
273: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
274: PetscTruth iascii;
275: PetscErrorCode ierr;
279: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
280: if (iascii) {
281: ascii->tab++;
282: }
283: return(0);
284: }
288: /*@
289: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
290: lines are tabbed.
292: Not Collective, but only first processor in set has any effect
294: Input Parameters:
295: . viewer - optained with PetscViewerASCIIOpen()
297: Level: developer
299: Fortran Note:
300: This routine is not supported in Fortran.
302: Concepts: PetscViewerASCII^formating
303: Concepts: tab^setting
305: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
306: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
307: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
308: @*/
309: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
310: {
311: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
312: PetscErrorCode ierr;
313: PetscTruth iascii;
317: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
318: if (iascii) {
319: if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
320: ascii->tab--;
321: }
322: return(0);
323: }
327: /*@
328: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
330: Not Collective, but only first processor in set has any effect
332: Input Parameters:
333: + viewer - optained with PetscViewerASCIIOpen()
334: - flg - PETSC_YES or PETSC_NO
336: Level: developer
338: Fortran Note:
339: This routine is not supported in Fortran.
341: Concepts: PetscViewerASCII^formating
342: Concepts: tab^setting
344: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
345: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
346: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
347: @*/
348: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
349: {
350: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
351: PetscTruth iascii;
352: PetscErrorCode ierr;
356: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
357: if (iascii) {
358: if (flg) {
359: ascii->tab = ascii->tab_store;
360: } else {
361: ascii->tab_store = ascii->tab;
362: ascii->tab = 0;
363: }
364: }
365: return(0);
366: }
368: /* ----------------------------------------------------------------------- */
370: #include src/sys/fileio/mprint.h
374: /*@C
375: PetscViewerASCIIPrintf - Prints to a file, only from the first
376: processor in the PetscViewer
378: Not Collective, but only first processor in set has any effect
380: Input Parameters:
381: + viewer - optained with PetscViewerASCIIOpen()
382: - format - the usual printf() format string
384: Level: developer
386: Fortran Note:
387: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
388: That is, you can only pass a single character string from Fortran.
390: Concepts: PetscViewerASCII^printing
391: Concepts: printing^to file
392: Concepts: printf
394: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
395: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
396: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
397: @*/
398: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
399: {
400: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
401: PetscMPIInt rank;
402: PetscInt tab;
403: PetscErrorCode ierr;
404: FILE *fd = ascii->fd;
405: PetscTruth iascii;
406: int err;
411: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
412: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
414: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
415: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
416: if (!rank) {
417: va_list Argp;
418: if (ascii->bviewer) {
419: queuefile = fd;
420: }
422: tab = ascii->tab;
423: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
425: va_start(Argp,format);
426: PetscVFPrintf(fd,format,Argp);
427: err = fflush(fd);
428: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
429: if (petsc_history) {
430: tab = ascii->tab;
431: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
432: (*PetscVFPrintf)(petsc_history,format,Argp);
433: err = fflush(petsc_history);
434: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
435: }
436: va_end(Argp);
437: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
438: va_list Argp;
439: char *string;
441: PrintfQueue next;
442: PetscNew(struct _PrintfQueue,&next);
443: if (queue) {queue->next = next; queue = next;}
444: else {queuebase = queue = next;}
445: queuelength++;
446: string = next->string;
447: PetscMemzero(string,QUEUESTRINGSIZE);
448: tab = 2*ascii->tab;
449: while (tab--) {*string++ = ' ';}
450: va_start(Argp,format);
451: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
452: va_end(Argp);
453: }
454: return(0);
455: }
459: /*@C
460: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
462: Collective on PetscViewer
464: Input Parameters:
465: + viewer - the PetscViewer; either ASCII or binary
466: - name - the name of the file it should use
468: Level: advanced
470: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
471: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
473: @*/
474: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
475: {
476: PetscErrorCode ierr,(*f)(PetscViewer,const char[]);
481: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
482: if (f) {
483: (*f)(viewer,name);
484: }
485: return(0);
486: }
490: /*@C
491: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
493: Not Collective
495: Input Parameter:
496: . viewer - the PetscViewer; either ASCII or binary
498: Output Parameter:
499: . name - the name of the file it is using
501: Level: advanced
503: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
505: @*/
506: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,char **name)
507: {
508: PetscErrorCode ierr,(*f)(PetscViewer,char **);
512: PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
513: if (f) {
514: (*f)(viewer,name);
515: }
516: return(0);
517: }
522: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
523: {
524: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
527: *name = vascii->filename;
528: return(0);
529: }
536: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
537: {
538: PetscErrorCode ierr;
539: size_t len;
540: char fname[PETSC_MAX_PATH_LEN],*gz;
541: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
542: PetscTruth isstderr,isstdout;
543: PetscMPIInt rank;
546: if (!name) return(0);
547: PetscStrfree(vascii->filename);
548: PetscStrallocpy(name,&vascii->filename);
550: /* Is this file to be compressed */
551: vascii->storecompressed = PETSC_FALSE;
552: PetscStrstr(vascii->filename,".gz",&gz);
553: if (gz) {
554: PetscStrlen(gz,&len);
555: if (len == 3) {
556: *gz = 0;
557: vascii->storecompressed = PETSC_TRUE;
558: }
559: }
560: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
561: if (!rank) {
562: PetscStrcmp(name,"stderr",&isstderr);
563: PetscStrcmp(name,"stdout",&isstdout);
564: /* empty filename means stdout */
565: if (name[0] == 0) isstdout = PETSC_TRUE;
566: if (isstderr) vascii->fd = PETSC_STDERR;
567: else if (isstdout) vascii->fd = PETSC_STDOUT;
568: else {
571: PetscFixFilename(name,fname);
572: switch(vascii->mode) {
573: case FILE_MODE_READ:
574: vascii->fd = fopen(fname,"r");
575: break;
576: case FILE_MODE_WRITE:
577: vascii->fd = fopen(fname,"w");
578: break;
579: case FILE_MODE_APPEND:
580: vascii->fd = fopen(fname,"a");
581: break;
582: case FILE_MODE_UPDATE:
583: vascii->fd = fopen(fname,"r+");
584: if (!vascii->fd) {
585: vascii->fd = fopen(fname,"w+");
586: }
587: break;
588: case FILE_MODE_APPEND_UPDATE:
589: /* I really want a file which is opened at the end for updating,
590: not a+, which opens at the beginning, but makes writes at the end.
591: */
592: vascii->fd = fopen(fname,"r+");
593: if (!vascii->fd) {
594: vascii->fd = fopen(fname,"w+");
595: } else {
596: fseek(vascii->fd, 0, SEEK_END);
597: }
598: break;
599: default:
600: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
601: }
602: if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
603: }
604: }
605: #if defined(PETSC_USE_LOG)
606: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
607: #endif
608: return(0);
609: }
614: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
615: {
616: PetscMPIInt rank;
617: PetscErrorCode ierr;
618: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
619: const char *name;
622: if (vascii->sviewer) {
623: SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
624: }
625: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
626: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
627: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
628: ovascii->fd = vascii->fd;
629: ovascii->tab = vascii->tab;
631: vascii->sviewer = *outviewer;
633: (*outviewer)->format = viewer->format;
634: (*outviewer)->iformat = viewer->iformat;
636: PetscObjectGetName((PetscObject)viewer,&name);
637: PetscObjectSetName((PetscObject)(*outviewer),name);
639: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
640: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
641: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
642: if (rank) {
643: (*outviewer)->ops->flush = 0;
644: } else {
645: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
646: }
647: return(0);
648: }
652: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
653: {
654: PetscErrorCode ierr;
655: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
656: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
659: if (!ascii->sviewer) {
660: SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
661: }
662: if (ascii->sviewer != *outviewer) {
663: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
664: }
666: ascii->sviewer = 0;
667: vascii->fd = PETSC_STDOUT;
668: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
669: PetscViewerDestroy(*outviewer);
670: PetscViewerFlush(viewer);
671: return(0);
672: }
676: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
677: {
678: PetscMPIInt rank;
679: PetscErrorCode ierr;
680: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
681: const char *name;
684: if (vascii->sviewer) {
685: SETERRQ(PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
686: }
687: /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
688: PetscViewerCreate(subcomm,outviewer);
689: PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
690: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
691: ovascii->fd = vascii->fd;
692: ovascii->tab = vascii->tab;
694: vascii->sviewer = *outviewer;
696: (*outviewer)->format = viewer->format;
697: (*outviewer)->iformat = viewer->iformat;
699: PetscObjectGetName((PetscObject)viewer,&name);
700: PetscObjectSetName((PetscObject)(*outviewer),name);
702: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
703: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
704: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
705: /* following might not be correct??? */
706: if (rank) {
707: (*outviewer)->ops->flush = 0;
708: } else {
709: (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
710: }
711: return(0);
712: }
716: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
717: {
718: PetscErrorCode ierr;
719: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
720: PetscViewer_ASCII *ascii = (PetscViewer_ASCII *)viewer->data;
723: if (!ascii->sviewer) {
724: SETERRQ(PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
725: }
726: if (ascii->sviewer != *outviewer) {
727: SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
728: }
730: ascii->sviewer = 0;
731: vascii->fd = PETSC_STDOUT;
732: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
733: PetscViewerDestroy(*outviewer);
734: PetscViewerFlush(viewer);
735: return(0);
736: }
741: PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
742: {
743: PetscViewer_ASCII *vascii;
744: PetscErrorCode ierr;
747: PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
748: viewer->data = (void*)vascii;
750: viewer->ops->destroy = PetscViewerDestroy_ASCII;
751: viewer->ops->flush = PetscViewerFlush_ASCII;
752: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
753: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
754: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
755: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
757: /* defaults to stdout unless set with PetscViewerFileSetName() */
758: vascii->fd = PETSC_STDOUT;
759: vascii->mode = FILE_MODE_WRITE;
760: vascii->bviewer = 0;
761: vascii->sviewer = 0;
762: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
763: viewer->iformat = 0;
764: vascii->tab = 0;
765: vascii->tab_store = 0;
766: vascii->filename = 0;
768: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
769: PetscViewerFileSetName_ASCII);
770: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
771: PetscViewerFileGetName_ASCII);
772: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
773: PetscViewerFileGetMode_ASCII);
774: PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
775: PetscViewerFileSetMode_ASCII);
777: return(0);
778: }
784: /*@C
785: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
786: several processors. Output of the first processor is followed by that of the
787: second, etc.
789: Not Collective, must call collective PetscViewerFlush() to get the results out
791: Input Parameters:
792: + viewer - the ASCII PetscViewer
793: - format - the usual printf() format string
795: Level: intermediate
797: Fortran Note:
798: Can only print a single character* string
800: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
801: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
802: PetscViewerASCIIPrintf()
804: @*/
805: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
806: {
807: PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
808: PetscErrorCode ierr;
809: PetscMPIInt rank;
810: PetscInt tab = vascii->tab;
811: MPI_Comm comm;
812: FILE *fp;
813: PetscTruth iascii;
814: int err;
819: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
820: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
822: comm = ((PetscObject)viewer)->comm;
823: fp = vascii->fd;
824: MPI_Comm_rank(comm,&rank);
825: if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
826:
828: /* First processor prints immediately to fp */
829: if (!rank) {
830: va_list Argp;
832: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp," ");}
834: va_start(Argp,format);
835: (*PetscVFPrintf)(fp,format,Argp);
836: err = fflush(fp);
837: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
838: queuefile = fp;
839: if (petsc_history) {
840: (*PetscVFPrintf)(petsc_history,format,Argp);
841: err = fflush(petsc_history);
842: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
843: }
844: va_end(Argp);
845: } else { /* other processors add to local queue */
846: char *string;
847: va_list Argp;
848: PrintfQueue next;
850: PetscNew(struct _PrintfQueue,&next);
851: if (queue) {queue->next = next; queue = next;}
852: else {queuebase = queue = next;}
853: queuelength++;
854: string = next->string;
855: PetscMemzero(string,QUEUESTRINGSIZE);
856: tab *= 2;
857: while (tab--) {*string++ = ' ';}
858: va_start(Argp,format);
859: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
860: va_end(Argp);
861: }
862: return(0);
863: }
868: /*@C
869: PetscViewerASCIIMonitorCreate - Opens an ASCII file as a monitor object, suitable for the default KSP, SNES and TS monitors
871: Collective on MPI_Comm
873: Input Parameters:
874: + comm - the communicator
875: . name - the file name
876: - tabs - how far in the text should be tabbed
878: Output Parameter:
879: . lab - the context to be used with KSP/SNES/TSMonitorSet()
881: Level: advanced
883: Notes:
884: This can be destroyed with PetscViewerASCIIMonitorDestroy().
886: See PetscViewerASCIIOpen()
888: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorDestroy()
890: @*/
891: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
892: {
896: PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
897: PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
898: (*ctx)->tabs = tabs;
899: return(0);
900: }
904: /*@C
905: PetscViewerASCIIMonitorDestroys - removes a monitor context.
907: Collective on PetscViewerASCIIMonitor
909: Input Parameters:
910: . ctx - the monitor context created with PetscViewerASCIIMonitorCreate()
912: Level: advanced
914: Notes:
915: This is rarely called by users, it is usually called when the KSP, SNES or TS object is destroyed
917: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate()
919: @*/
920: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
921: {
925: PetscViewerDestroy(ctx->viewer);
926: PetscFree(ctx);
927: return(0);
928: }
932: /*@C
933: PetscViewerASCIIMonitorPrintf - Prints to the viewer associated with this monitor context
935: Not Collective, but only first processor in set has any effect
937: Input Parameters:
938: + ctx - the context obtained with PetscViewerASCIIMonitorCreate()
939: - format - the usual printf() format string
941: Level: developer
943: Developer Notes: This code is virtually identical to PetscViewerASCIIPrintf(), however the code
944: could not simply be called from here due to the var args.
946: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
947: PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()
950: @*/
951: PetscErrorCode PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
952: {
953: PetscViewer viewer = ctx->viewer;
954: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
955: PetscMPIInt rank;
956: PetscInt tab;
957: PetscErrorCode ierr;
958: FILE *fd = ascii->fd;
959: PetscTruth iascii;
960: int err;
965: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
966: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
968: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
969: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
970: if (!rank) {
971: va_list Argp;
972: if (ascii->bviewer) {
973: queuefile = fd;
974: }
976: tab = ascii->tab + ctx->tabs;
977: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
979: va_start(Argp,format);
980: (*PetscVFPrintf)(fd,format,Argp);
981: err = fflush(fd);
982: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
983: if (petsc_history) {
984: tab = ascii->tab + ctx->tabs;
985: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
986: (*PetscVFPrintf)(petsc_history,format,Argp);
987: err = fflush(petsc_history);
988: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
989: }
990: va_end(Argp);
991: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
992: va_list Argp;
993: char *string;
995: PrintfQueue next;
996: PetscNew(struct _PrintfQueue,&next);
997: if (queue) {queue->next = next; queue = next;}
998: else {queuebase = queue = next;}
999: queuelength++;
1000: string = next->string;
1001: PetscMemzero(string,QUEUESTRINGSIZE);
1002: tab = 2*(ascii->tab + ctx->tabs);
1003: while (tab--) {*string++ = ' ';}
1004: va_start(Argp,format);
1005: PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
1006: va_end(Argp);
1007: }
1008: return(0);
1009: }