Actual source code: filev.c
petsc-3.5.4 2015-05-23
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/
4: #define QUEUESTRINGSIZE 8192
8: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
9: {
10: PetscErrorCode ierr;
11: PetscMPIInt rank;
12: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
13: int err;
16: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
17: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
18: if (vascii->fd && vascii->closefile) {
19: err = fclose(vascii->fd);
20: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
21: }
22: if (vascii->storecompressed) {
23: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
24: FILE *fp;
25: PetscStrcpy(par,"gzip ");
26: PetscStrcat(par,vascii->filename);
27: #if defined(PETSC_HAVE_POPEN)
28: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
29: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
30: PetscPClose(PETSC_COMM_SELF,fp,NULL);
31: #else
32: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
33: #endif
34: }
35: }
36: PetscFree(vascii->filename);
37: return(0);
38: }
40: /* ----------------------------------------------------------------------*/
43: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
44: {
45: PetscErrorCode ierr;
46: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
47: PetscViewerLink *vlink;
48: PetscBool flg;
51: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
52: PetscViewerFileClose_ASCII(viewer);
53: PetscFree(vascii);
55: /* remove the viewer from the list in the MPI Communicator */
56: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
57: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
58: }
60: MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
61: if (flg) {
62: if (vlink && vlink->viewer == viewer) {
63: MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
64: PetscFree(vlink);
65: } else {
66: while (vlink && vlink->next) {
67: if (vlink->next->viewer == viewer) {
68: PetscViewerLink *nv = vlink->next;
69: vlink->next = vlink->next->next;
70: PetscFree(nv);
71: }
72: vlink = vlink->next;
73: }
74: }
75: }
76: return(0);
77: }
81: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
82: {
83: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
84: PetscErrorCode ierr;
87: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
88: vascii->bviewer = NULL;
89: return(0);
90: }
94: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
95: {
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
97: PetscErrorCode ierr;
100: PetscViewerRestoreSubcomm(vascii->subviewer,PetscObjectComm((PetscObject)viewer),&viewer);
101: vascii->subviewer = NULL;
102: return(0);
103: }
107: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
108: {
109: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
110: int err;
113: err = fflush(vascii->fd);
114: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
115: return(0);
116: }
120: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
121: {
122: PetscMPIInt rank;
123: PetscErrorCode ierr;
124: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
125: int err;
128: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
129: /* fflush() fails on OSX for read-only descriptors */
130: if (!rank && (vascii->mode != FILE_MODE_READ)) {
131: err = fflush(vascii->fd);
132: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
133: }
135: if (vascii->allowsynchronized) {
136: /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */
137: PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer),vascii->fd);
138: }
139: return(0);
140: }
144: /*@C
145: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
147: Not Collective
149: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
150: - fd - file pointer
152: Level: intermediate
154: Fortran Note:
155: This routine is not supported in Fortran.
157: Concepts: PetscViewer^file pointer
158: Concepts: file pointer^getting from PetscViewer
160: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
161: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
162: @*/
163: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
164: {
165: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
168: *fd = vascii->fd;
169: return(0);
170: }
174: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
175: {
176: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
179: *mode = vascii->mode;
180: return(0);
181: }
185: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
186: {
187: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
190: vascii->mode = mode;
191: return(0);
192: }
194: /*
195: If petsc_history is on, then all Petsc*Printf() results are saved
196: if the appropriate (usually .petschistory) file.
197: */
198: extern FILE *petsc_history;
202: /*@
203: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
205: Not Collective, but only first processor in set has any effect
207: Input Parameters:
208: + viewer - optained with PetscViewerASCIIOpen()
209: - tabs - number of tabs
211: Level: developer
213: Fortran Note:
214: This routine is not supported in Fortran.
216: Concepts: PetscViewerASCII^formating
217: Concepts: tab^setting
219: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
220: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
221: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
222: @*/
223: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
224: {
225: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
226: PetscBool iascii;
227: PetscErrorCode ierr;
231: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
232: if (iascii) ascii->tab = tabs;
233: return(0);
234: }
238: /*@
239: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
241: Not Collective, meaningful on first processor only.
243: Input Parameters:
244: . viewer - optained with PetscViewerASCIIOpen()
245: Output Parameters:
246: . tabs - number of tabs
248: Level: developer
250: Fortran Note:
251: This routine is not supported in Fortran.
253: Concepts: PetscViewerASCII^formating
254: Concepts: tab^retrieval
256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
257: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259: @*/
260: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
261: {
262: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
263: PetscBool iascii;
264: PetscErrorCode ierr;
268: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
269: if (iascii && tabs) *tabs = ascii->tab;
270: return(0);
271: }
275: /*@
276: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
278: Not Collective, but only first processor in set has any effect
280: Input Parameters:
281: + viewer - optained with PetscViewerASCIIOpen()
282: - tabs - number of tabs
284: Level: developer
286: Fortran Note:
287: This routine is not supported in Fortran.
289: Concepts: PetscViewerASCII^formating
290: Concepts: tab^setting
292: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
293: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
294: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
295: @*/
296: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
297: {
298: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
299: PetscBool iascii;
300: PetscErrorCode ierr;
304: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
305: if (iascii) ascii->tab += tabs;
306: return(0);
307: }
311: /*@
312: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
314: Not Collective, but only first processor in set has any effect
316: Input Parameters:
317: + viewer - optained with PetscViewerASCIIOpen()
318: - tabs - number of tabs
320: Level: developer
322: Fortran Note:
323: This routine is not supported in Fortran.
325: Concepts: PetscViewerASCII^formating
326: Concepts: tab^setting
328: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
329: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
330: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
331: @*/
332: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
333: {
334: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
335: PetscBool iascii;
336: PetscErrorCode ierr;
340: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
341: if (iascii) ascii->tab -= tabs;
342: return(0);
343: }
347: /*@C
348: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
350: Collective on PetscViewer
352: Input Parameters:
353: + viewer - optained with PetscViewerASCIIOpen()
354: - allow - PETSC_TRUE to allow the synchronized printing
356: Level: intermediate
358: Concepts: PetscViewerASCII^formating
359: Concepts: tab^setting
361: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
362: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
363: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
364: @*/
365: PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
366: {
367: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
368: PetscBool iascii;
369: PetscErrorCode ierr;
373: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
374: if (iascii) ascii->allowsynchronized = allow;
375: return(0);
376: }
380: /*@
381: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
382: lines are tabbed.
384: Not Collective, but only first processor in set has any effect
386: Input Parameters:
387: . viewer - optained with PetscViewerASCIIOpen()
389: Level: developer
391: Fortran Note:
392: This routine is not supported in Fortran.
394: Concepts: PetscViewerASCII^formating
395: Concepts: tab^setting
397: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
398: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
399: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
400: @*/
401: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
402: {
403: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
404: PetscBool iascii;
405: PetscErrorCode ierr;
409: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
410: if (iascii) ascii->tab++;
411: return(0);
412: }
416: /*@
417: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
418: lines are tabbed.
420: Not Collective, but only first processor in set has any effect
422: Input Parameters:
423: . viewer - optained with PetscViewerASCIIOpen()
425: Level: developer
427: Fortran Note:
428: This routine is not supported in Fortran.
430: Concepts: PetscViewerASCII^formating
431: Concepts: tab^setting
433: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
434: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
435: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
436: @*/
437: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
438: {
439: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
440: PetscErrorCode ierr;
441: PetscBool iascii;
445: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
446: if (iascii) {
447: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
448: ascii->tab--;
449: }
450: return(0);
451: }
455: /*@
456: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
458: Not Collective, but only first processor in set has any effect
460: Input Parameters:
461: + viewer - optained with PetscViewerASCIIOpen()
462: - flg - PETSC_TRUE or PETSC_FALSE
464: Level: developer
466: Fortran Note:
467: This routine is not supported in Fortran.
469: Concepts: PetscViewerASCII^formating
470: Concepts: tab^setting
472: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
473: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
474: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
475: @*/
476: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
477: {
478: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
479: PetscBool iascii;
480: PetscErrorCode ierr;
484: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
485: if (iascii) {
486: if (flg) ascii->tab = ascii->tab_store;
487: else {
488: ascii->tab_store = ascii->tab;
489: ascii->tab = 0;
490: }
491: }
492: return(0);
493: }
495: /* ----------------------------------------------------------------------- */
497: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
501: /*@C
502: PetscViewerASCIIPrintf - Prints to a file, only from the first
503: processor in the PetscViewer
505: Not Collective, but only first processor in set has any effect
507: Input Parameters:
508: + viewer - optained with PetscViewerASCIIOpen()
509: - format - the usual printf() format string
511: Level: developer
513: Fortran Note:
514: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
515: That is, you can only pass a single character string from Fortran.
517: Concepts: PetscViewerASCII^printing
518: Concepts: printing^to file
519: Concepts: printf
521: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
522: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
523: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
524: @*/
525: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
526: {
527: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
528: PetscMPIInt rank;
529: PetscInt tab,intab = ascii->tab;
530: PetscErrorCode ierr;
531: FILE *fd = ascii->fd;
532: PetscBool iascii,issingleton = PETSC_FALSE;
533: int err;
538: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
539: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
540: if (ascii->bviewer) {
541: viewer = ascii->bviewer;
542: ascii = (PetscViewer_ASCII*)viewer->data;
543: fd = ascii->fd;
544: issingleton = PETSC_TRUE;
545: }
547: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
548: if (!rank) {
549: va_list Argp;
550: tab = intab;
551: while (tab--) {
552: PetscFPrintf(PETSC_COMM_SELF,fd," ");
553: }
555: va_start(Argp,format);
556: (*PetscVFPrintf)(fd,format,Argp);
557: err = fflush(fd);
558: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
559: if (petsc_history) {
560: va_start(Argp,format);
561: tab = intab;
562: while (tab--) {
563: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
564: }
565: (*PetscVFPrintf)(petsc_history,format,Argp);
566: err = fflush(petsc_history);
567: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
568: }
569: va_end(Argp);
570: } else if (issingleton) {
571: char *string;
572: va_list Argp;
573: size_t fullLength;
574: PrintfQueue next;
576: PetscNew(&next);
577: if (petsc_printfqueue) {
578: petsc_printfqueue->next = next;
579: petsc_printfqueue = next;
580: } else {
581: petsc_printfqueuebase = petsc_printfqueue = next;
582: }
583: petsc_printfqueuelength++;
584: next->size = QUEUESTRINGSIZE;
585: PetscMalloc(next->size*sizeof(char), &next->string);
586: PetscMemzero(next->string,next->size);
587: string = next->string;
588: tab = intab;
589: tab *= 2;
590: while (tab--) {
591: *string++ = ' ';
592: }
593: va_start(Argp,format);
594: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
595: va_end(Argp);
596: }
597: return(0);
598: }
602: /*@C
603: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
605: Collective on PetscViewer
607: Input Parameters:
608: + viewer - the PetscViewer; either ASCII or binary
609: - name - the name of the file it should use
611: Level: advanced
613: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
614: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
616: @*/
617: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
618: {
624: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
625: return(0);
626: }
630: /*@C
631: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
633: Not Collective
635: Input Parameter:
636: . viewer - the PetscViewer; either ASCII or binary
638: Output Parameter:
639: . name - the name of the file it is using
641: Level: advanced
643: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
645: @*/
646: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
647: {
652: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
653: return(0);
654: }
658: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
659: {
660: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
663: *name = vascii->filename;
664: return(0);
665: }
669: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
670: {
671: PetscErrorCode ierr;
672: size_t len;
673: char fname[PETSC_MAX_PATH_LEN],*gz;
674: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
675: PetscBool isstderr,isstdout;
676: PetscMPIInt rank;
679: PetscViewerFileClose_ASCII(viewer);
680: if (!name) return(0);
681: PetscStrallocpy(name,&vascii->filename);
683: /* Is this file to be compressed */
684: vascii->storecompressed = PETSC_FALSE;
686: PetscStrstr(vascii->filename,".gz",&gz);
687: if (gz) {
688: PetscStrlen(gz,&len);
689: if (len == 3) {
690: *gz = 0;
691: vascii->storecompressed = PETSC_TRUE;
692: }
693: }
694: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
695: if (!rank) {
696: PetscStrcmp(name,"stderr",&isstderr);
697: PetscStrcmp(name,"stdout",&isstdout);
698: /* empty filename means stdout */
699: if (name[0] == 0) isstdout = PETSC_TRUE;
700: if (isstderr) vascii->fd = PETSC_STDERR;
701: else if (isstdout) vascii->fd = PETSC_STDOUT;
702: else {
705: PetscFixFilename(name,fname);
706: switch (vascii->mode) {
707: case FILE_MODE_READ:
708: vascii->fd = fopen(fname,"r");
709: break;
710: case FILE_MODE_WRITE:
711: vascii->fd = fopen(fname,"w");
712: break;
713: case FILE_MODE_APPEND:
714: vascii->fd = fopen(fname,"a");
715: break;
716: case FILE_MODE_UPDATE:
717: vascii->fd = fopen(fname,"r+");
718: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
719: break;
720: case FILE_MODE_APPEND_UPDATE:
721: /* I really want a file which is opened at the end for updating,
722: not a+, which opens at the beginning, but makes writes at the end.
723: */
724: vascii->fd = fopen(fname,"r+");
725: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
726: else {
727: fseek(vascii->fd, 0, SEEK_END);
728: }
729: break;
730: default:
731: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
732: }
733: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
734: }
735: }
736: #if defined(PETSC_USE_LOG)
737: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
738: #endif
739: return(0);
740: }
744: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
745: {
746: PetscMPIInt rank;
747: PetscErrorCode ierr;
748: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
749: const char *name;
752: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
753: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
754: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
755: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
756: ovascii->fd = vascii->fd;
757: ovascii->tab = vascii->tab;
759: vascii->sviewer = *outviewer;
761: (*outviewer)->format = viewer->format;
763: PetscObjectGetName((PetscObject)viewer,&name);
764: PetscObjectSetName((PetscObject)(*outviewer),name);
766: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
767: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
768: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
769: if (rank) (*outviewer)->ops->flush = 0;
770: else (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
771: return(0);
772: }
776: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
777: {
778: PetscErrorCode ierr;
779: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
780: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
783: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
784: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
786: ascii->sviewer = 0;
787: vascii->fd = PETSC_STDOUT;
788: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
789: PetscViewerDestroy(outviewer);
790: PetscViewerFlush(viewer);
791: return(0);
792: }
796: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
797: {
798: PetscErrorCode ierr;
799: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
800: const char *name;
803: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
804: /* Note that we need to open vascii->filename for the subcomm:
805: we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
806: Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
807: will return the current viewer, having increfed it.
808: */
809: PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
810: if (*outviewer == viewer) return(0);
811: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
813: ovascii->tab = vascii->tab;
814: vascii->sviewer = *outviewer;
816: (*outviewer)->format = viewer->format;
818: PetscObjectGetName((PetscObject)viewer,&name);
819: PetscObjectSetName((PetscObject)(*outviewer),name);
821: ((PetscViewer_ASCII*)((*outviewer)->data))->subviewer = viewer;
823: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
824: return(0);
825: }
829: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
830: {
831: PetscErrorCode ierr;
832: PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
833: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
836: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
837: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
839: ascii->sviewer = 0;
840: oascii->fd = PETSC_STDOUT;
841: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
843: PetscViewerDestroy(outviewer);
844: PetscViewerFlush(viewer);
845: return(0);
846: }
850: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
851: {
852: PetscErrorCode ierr;
853: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
856: if (ascii->filename) {
857: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
858: }
859: return(0);
860: }
864: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
865: {
866: PetscViewer_ASCII *vascii;
867: PetscErrorCode ierr;
870: PetscNewLog(viewer,&vascii);
871: viewer->data = (void*)vascii;
873: viewer->ops->destroy = PetscViewerDestroy_ASCII;
874: viewer->ops->flush = PetscViewerFlush_ASCII;
875: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
876: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
877: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
878: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
879: viewer->ops->view = PetscViewerView_ASCII;
881: /* defaults to stdout unless set with PetscViewerFileSetName() */
882: vascii->fd = PETSC_STDOUT;
883: vascii->mode = FILE_MODE_WRITE;
884: vascii->bviewer = 0;
885: vascii->subviewer = 0;
886: vascii->sviewer = 0;
887: vascii->tab = 0;
888: vascii->tab_store = 0;
889: vascii->filename = 0;
890: vascii->closefile = PETSC_TRUE;
892: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
893: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
894: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
895: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
896: return(0);
897: }
902: /*@C
903: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
904: several processors. Output of the first processor is followed by that of the
905: second, etc.
907: Not Collective, must call collective PetscViewerFlush() to get the results out
909: Input Parameters:
910: + viewer - the ASCII PetscViewer
911: - format - the usual printf() format string
913: Level: intermediate
915: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
917: Fortran Note:
918: Can only print a single character* string
920: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
921: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
922: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
924: @*/
925: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
926: {
927: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
928: PetscErrorCode ierr;
929: PetscMPIInt rank,size;
930: PetscInt tab = vascii->tab;
931: MPI_Comm comm;
932: FILE *fp;
933: PetscBool iascii;
934: int err;
939: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
940: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
941: MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);
942: if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
943: if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
945: PetscObjectGetComm((PetscObject)viewer,&comm);
946: fp = vascii->fd;
947: MPI_Comm_rank(comm,&rank);
949: /* First processor prints immediately to fp */
950: if (!rank) {
951: va_list Argp;
953: while (tab--) {
954: PetscFPrintf(PETSC_COMM_SELF,fp," ");
955: }
957: va_start(Argp,format);
958: (*PetscVFPrintf)(fp,format,Argp);
959: err = fflush(fp);
960: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
961: if (petsc_history) {
962: va_start(Argp,format);
963: (*PetscVFPrintf)(petsc_history,format,Argp);
964: err = fflush(petsc_history);
965: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
966: }
967: va_end(Argp);
968: } else { /* other processors add to local queue */
969: char *string;
970: va_list Argp;
971: size_t fullLength;
972: PrintfQueue next;
974: PetscNew(&next);
975: if (petsc_printfqueue) {
976: petsc_printfqueue->next = next;
977: petsc_printfqueue = next;
978: } else {
979: petsc_printfqueuebase = petsc_printfqueue = next;
980: }
981: petsc_printfqueuelength++;
982: next->size = QUEUESTRINGSIZE;
983: PetscMalloc1(next->size, &next->string);
984: PetscMemzero(next->string,next->size);
985: string = next->string;
986: tab *= 2;
987: while (tab--) {
988: *string++ = ' ';
989: }
990: va_start(Argp,format);
991: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
992: va_end(Argp);
993: }
994: return(0);
995: }