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: va_start(Argp,format);
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: va_start(Argp,format);
846: (*PetscVFPrintf)(petsc_history,format,Argp);
847: err = fflush(petsc_history);
848: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
849: }
850: va_end(Argp);
851: } else { /* other processors add to local queue */
852: char *string;
853: va_list Argp;
854: int fullLength;
855: PrintfQueue next;
857: PetscNew(struct _PrintfQueue,&next);
858: if (queue) {queue->next = next; queue = next;}
859: else {queuebase = queue = next;}
860: queuelength++;
861: next->size = QUEUESTRINGSIZE;
862: PetscMalloc(next->size*sizeof(char), &next->string);
863: PetscMemzero(next->string,next->size);
864: string = next->string;
865: tab *= 2;
866: while (tab--) {*string++ = ' ';}
867: va_start(Argp,format);
868: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
869: va_end(Argp);
870: }
871: return(0);
872: }
877: /*@C
878: PetscViewerASCIIMonitorCreate - Opens an ASCII file as a monitor object, suitable for the default KSP, SNES and TS monitors
880: Collective on MPI_Comm
882: Input Parameters:
883: + comm - the communicator
884: . name - the file name
885: - tabs - how far in the text should be tabbed
887: Output Parameter:
888: . lab - the context to be used with KSP/SNES/TSMonitorSet()
890: Level: advanced
892: Notes:
893: This can be destroyed with PetscViewerASCIIMonitorDestroy().
895: See PetscViewerASCIIOpen()
897: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorDestroy()
899: @*/
900: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
901: {
905: PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
906: PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
907: (*ctx)->tabs = tabs;
908: return(0);
909: }
913: /*@C
914: PetscViewerASCIIMonitorDestroys - removes a monitor context.
916: Collective on PetscViewerASCIIMonitor
918: Input Parameters:
919: . ctx - the monitor context created with PetscViewerASCIIMonitorCreate()
921: Level: advanced
923: Notes:
924: This is rarely called by users, it is usually called when the KSP, SNES or TS object is destroyed
926: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate()
928: @*/
929: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
930: {
934: PetscViewerDestroy(ctx->viewer);
935: PetscFree(ctx);
936: return(0);
937: }
941: /*@C
942: PetscViewerASCIIMonitorPrintf - Prints to the viewer associated with this monitor context
944: Not Collective, but only first processor in set has any effect
946: Input Parameters:
947: + ctx - the context obtained with PetscViewerASCIIMonitorCreate()
948: - format - the usual printf() format string
950: Level: developer
952: Developer Notes: This code is virtually identical to PetscViewerASCIIPrintf(), however the code
953: could not simply be called from here due to the var args.
955: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
956: PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()
959: @*/
960: PetscErrorCode PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
961: {
962: PetscViewer viewer = ctx->viewer;
963: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
964: PetscMPIInt rank;
965: PetscInt tab;
966: PetscErrorCode ierr;
967: FILE *fd = ascii->fd;
968: PetscTruth iascii;
969: int err;
974: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
975: if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
977: MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
978: if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
979: if (!rank) {
980: va_list Argp;
981: if (ascii->bviewer) {
982: queuefile = fd;
983: }
985: tab = ascii->tab + ctx->tabs;
986: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
988: va_start(Argp,format);
989: (*PetscVFPrintf)(fd,format,Argp);
990: err = fflush(fd);
991: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
992: if (petsc_history) {
993: va_start(Argp,format);
994: tab = ascii->tab + ctx->tabs;
995: while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd," ");}
996: (*PetscVFPrintf)(petsc_history,format,Argp);
997: err = fflush(petsc_history);
998: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
999: }
1000: va_end(Argp);
1001: } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
1002: va_list Argp;
1003: int fullLength;
1004: char *string;
1005: PrintfQueue next;
1007: PetscNew(struct _PrintfQueue,&next);
1008: if (queue) {queue->next = next; queue = next;}
1009: else {queuebase = queue = next;}
1010: queuelength++;
1011: next->size = QUEUESTRINGSIZE;
1012: PetscMalloc(next->size*sizeof(char), &next->string);
1013: PetscMemzero(next->string,next->size);
1014: string = next->string;
1015: tab = 2*(ascii->tab + ctx->tabs);
1016: while (tab--) {*string++ = ' ';}
1017: va_start(Argp,format);
1018: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
1019: va_end(Argp);
1020: }
1021: return(0);
1022: }