Actual source code: filev.c
petsc-3.6.1 2015-08-06
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: if (vlink->next) {
64: MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
65: } else {
66: MPI_Attr_delete(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
67: }
68: PetscFree(vlink);
69: } else {
70: while (vlink && vlink->next) {
71: if (vlink->next->viewer == viewer) {
72: PetscViewerLink *nv = vlink->next;
73: vlink->next = vlink->next->next;
74: PetscFree(nv);
75: }
76: vlink = vlink->next;
77: }
78: }
79: }
80: return(0);
81: }
85: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
86: {
87: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
88: PetscErrorCode ierr;
91: PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
92: vascii->bviewer = NULL;
93: return(0);
94: }
98: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
99: {
100: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
101: PetscErrorCode ierr;
104: PetscViewerRestoreSubcomm(vascii->subviewer,PetscObjectComm((PetscObject)viewer),&viewer);
105: vascii->subviewer = NULL;
106: return(0);
107: }
111: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
112: {
113: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
114: int err;
117: err = fflush(vascii->fd);
118: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
119: return(0);
120: }
124: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
125: {
126: PetscMPIInt rank;
127: PetscErrorCode ierr;
128: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
129: int err;
132: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
133: /* fflush() fails on OSX for read-only descriptors */
134: if (!rank && (vascii->mode != FILE_MODE_READ)) {
135: err = fflush(vascii->fd);
136: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
137: }
139: if (vascii->allowsynchronized) {
140: /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf() */
141: PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer),vascii->fd);
142: }
143: return(0);
144: }
148: /*@C
149: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
151: Not Collective
153: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
154: - fd - file pointer
156: Level: intermediate
158: Fortran Note:
159: This routine is not supported in Fortran.
161: Concepts: PetscViewer^file pointer
162: Concepts: file pointer^getting from PetscViewer
164: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
165: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
166: @*/
167: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
168: {
169: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
172: *fd = vascii->fd;
173: return(0);
174: }
178: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
179: {
180: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
183: *mode = vascii->mode;
184: return(0);
185: }
189: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
190: {
191: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
194: vascii->mode = mode;
195: return(0);
196: }
198: /*
199: If petsc_history is on, then all Petsc*Printf() results are saved
200: if the appropriate (usually .petschistory) file.
201: */
202: extern FILE *petsc_history;
206: /*@
207: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
209: Not Collective, but only first processor in set has any effect
211: Input Parameters:
212: + viewer - optained with PetscViewerASCIIOpen()
213: - tabs - number of tabs
215: Level: developer
217: Fortran Note:
218: This routine is not supported in Fortran.
220: Concepts: PetscViewerASCII^formating
221: Concepts: tab^setting
223: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
224: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
225: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
226: @*/
227: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
228: {
229: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
230: PetscBool iascii;
231: PetscErrorCode ierr;
235: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
236: if (iascii) ascii->tab = tabs;
237: return(0);
238: }
242: /*@
243: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
245: Not Collective, meaningful on first processor only.
247: Input Parameters:
248: . viewer - optained with PetscViewerASCIIOpen()
249: Output Parameters:
250: . tabs - number of tabs
252: Level: developer
254: Fortran Note:
255: This routine is not supported in Fortran.
257: Concepts: PetscViewerASCII^formating
258: Concepts: tab^retrieval
260: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
261: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
262: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
263: @*/
264: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
265: {
266: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
267: PetscBool iascii;
268: PetscErrorCode ierr;
272: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
273: if (iascii && tabs) *tabs = ascii->tab;
274: return(0);
275: }
279: /*@
280: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
282: Not Collective, but only first processor in set has any effect
284: Input Parameters:
285: + viewer - optained with PetscViewerASCIIOpen()
286: - tabs - number of tabs
288: Level: developer
290: Fortran Note:
291: This routine is not supported in Fortran.
293: Concepts: PetscViewerASCII^formating
294: Concepts: tab^setting
296: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
297: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
298: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
299: @*/
300: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
301: {
302: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
303: PetscBool iascii;
304: PetscErrorCode ierr;
308: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
309: if (iascii) ascii->tab += tabs;
310: return(0);
311: }
315: /*@
316: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
318: Not Collective, but only first processor in set has any effect
320: Input Parameters:
321: + viewer - optained with PetscViewerASCIIOpen()
322: - tabs - number of tabs
324: Level: developer
326: Fortran Note:
327: This routine is not supported in Fortran.
329: Concepts: PetscViewerASCII^formating
330: Concepts: tab^setting
332: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
333: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
334: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
335: @*/
336: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
337: {
338: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
339: PetscBool iascii;
340: PetscErrorCode ierr;
344: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
345: if (iascii) ascii->tab -= tabs;
346: return(0);
347: }
351: /*@C
352: PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
354: Collective on PetscViewer
356: Input Parameters:
357: + viewer - optained with PetscViewerASCIIOpen()
358: - allow - PETSC_TRUE to allow the synchronized printing
360: Level: intermediate
362: Concepts: PetscViewerASCII^formating
363: Concepts: tab^setting
365: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
366: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
367: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
368: @*/
369: PetscErrorCode PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
370: {
371: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
372: PetscBool iascii;
373: PetscErrorCode ierr;
377: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
378: if (iascii) ascii->allowsynchronized = allow;
379: return(0);
380: }
384: /*@
385: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
386: lines are tabbed.
388: Not Collective, but only first processor in set has any effect
390: Input Parameters:
391: . viewer - optained with PetscViewerASCIIOpen()
393: Level: developer
395: Fortran Note:
396: This routine is not supported in Fortran.
398: Concepts: PetscViewerASCII^formating
399: Concepts: tab^setting
401: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
402: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
403: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
404: @*/
405: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
406: {
407: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
408: PetscBool iascii;
409: PetscErrorCode ierr;
413: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
414: if (iascii) ascii->tab++;
415: return(0);
416: }
420: /*@
421: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
422: lines are tabbed.
424: Not Collective, but only first processor in set has any effect
426: Input Parameters:
427: . viewer - optained with PetscViewerASCIIOpen()
429: Level: developer
431: Fortran Note:
432: This routine is not supported in Fortran.
434: Concepts: PetscViewerASCII^formating
435: Concepts: tab^setting
437: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
438: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
439: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
440: @*/
441: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
442: {
443: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
444: PetscErrorCode ierr;
445: PetscBool iascii;
449: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
450: if (iascii) {
451: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
452: ascii->tab--;
453: }
454: return(0);
455: }
459: /*@
460: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
462: Not Collective, but only first processor in set has any effect
464: Input Parameters:
465: + viewer - optained with PetscViewerASCIIOpen()
466: - flg - PETSC_TRUE or PETSC_FALSE
468: Level: developer
470: Fortran Note:
471: This routine is not supported in Fortran.
473: Concepts: PetscViewerASCII^formating
474: Concepts: tab^setting
476: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
477: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
478: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
479: @*/
480: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
481: {
482: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
483: PetscBool iascii;
484: PetscErrorCode ierr;
488: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
489: if (iascii) {
490: if (flg) ascii->tab = ascii->tab_store;
491: else {
492: ascii->tab_store = ascii->tab;
493: ascii->tab = 0;
494: }
495: }
496: return(0);
497: }
499: /* ----------------------------------------------------------------------- */
501: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */
505: /*@C
506: PetscViewerASCIIPrintf - Prints to a file, only from the first
507: processor in the PetscViewer
509: Not Collective, but only first processor in set has any effect
511: Input Parameters:
512: + viewer - optained with PetscViewerASCIIOpen()
513: - format - the usual printf() format string
515: Level: developer
517: Fortran Note:
518: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
519: That is, you can only pass a single character string from Fortran.
521: Concepts: PetscViewerASCII^printing
522: Concepts: printing^to file
523: Concepts: printf
525: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
526: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
527: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
528: @*/
529: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
530: {
531: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
532: PetscMPIInt rank;
533: PetscInt tab,intab = ascii->tab;
534: PetscErrorCode ierr;
535: FILE *fd = ascii->fd;
536: PetscBool iascii,issingleton = PETSC_FALSE;
537: int err;
542: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
543: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
544: if (ascii->bviewer) {
545: viewer = ascii->bviewer;
546: ascii = (PetscViewer_ASCII*)viewer->data;
547: fd = ascii->fd;
548: issingleton = PETSC_TRUE;
549: }
551: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
552: if (!rank) {
553: va_list Argp;
554: tab = intab;
555: while (tab--) {
556: PetscFPrintf(PETSC_COMM_SELF,fd," ");
557: }
559: va_start(Argp,format);
560: (*PetscVFPrintf)(fd,format,Argp);
561: err = fflush(fd);
562: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
563: if (petsc_history) {
564: va_start(Argp,format);
565: tab = intab;
566: while (tab--) {
567: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
568: }
569: (*PetscVFPrintf)(petsc_history,format,Argp);
570: err = fflush(petsc_history);
571: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
572: }
573: va_end(Argp);
574: } else if (issingleton) {
575: char *string;
576: va_list Argp;
577: size_t fullLength;
578: PrintfQueue next;
580: PetscNew(&next);
581: if (petsc_printfqueue) {
582: petsc_printfqueue->next = next;
583: petsc_printfqueue = next;
584: } else {
585: petsc_printfqueuebase = petsc_printfqueue = next;
586: }
587: petsc_printfqueuelength++;
588: next->size = QUEUESTRINGSIZE;
589: PetscCalloc1(next->size, &next->string);
590: string = next->string;
591: tab = intab;
592: tab *= 2;
593: while (tab--) {
594: *string++ = ' ';
595: }
596: va_start(Argp,format);
597: PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
598: va_end(Argp);
599: }
600: return(0);
601: }
605: /*@C
606: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
608: Collective on PetscViewer
610: Input Parameters:
611: + viewer - the PetscViewer; either ASCII or binary
612: - name - the name of the file it should use
614: Level: advanced
616: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
617: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
619: @*/
620: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
621: {
627: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
628: return(0);
629: }
633: /*@C
634: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
636: Not Collective
638: Input Parameter:
639: . viewer - the PetscViewer; either ASCII or binary
641: Output Parameter:
642: . name - the name of the file it is using
644: Level: advanced
646: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
648: @*/
649: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
650: {
655: PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
656: return(0);
657: }
661: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
662: {
663: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
666: *name = vascii->filename;
667: return(0);
668: }
672: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
673: {
674: PetscErrorCode ierr;
675: size_t len;
676: char fname[PETSC_MAX_PATH_LEN],*gz;
677: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
678: PetscBool isstderr,isstdout;
679: PetscMPIInt rank;
682: PetscViewerFileClose_ASCII(viewer);
683: if (!name) return(0);
684: PetscStrallocpy(name,&vascii->filename);
686: /* Is this file to be compressed */
687: vascii->storecompressed = PETSC_FALSE;
689: PetscStrstr(vascii->filename,".gz",&gz);
690: if (gz) {
691: PetscStrlen(gz,&len);
692: if (len == 3) {
693: *gz = 0;
694: vascii->storecompressed = PETSC_TRUE;
695: }
696: }
697: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
698: if (!rank) {
699: PetscStrcmp(name,"stderr",&isstderr);
700: PetscStrcmp(name,"stdout",&isstdout);
701: /* empty filename means stdout */
702: if (name[0] == 0) isstdout = PETSC_TRUE;
703: if (isstderr) vascii->fd = PETSC_STDERR;
704: else if (isstdout) vascii->fd = PETSC_STDOUT;
705: else {
708: PetscFixFilename(name,fname);
709: switch (vascii->mode) {
710: case FILE_MODE_READ:
711: vascii->fd = fopen(fname,"r");
712: break;
713: case FILE_MODE_WRITE:
714: vascii->fd = fopen(fname,"w");
715: break;
716: case FILE_MODE_APPEND:
717: vascii->fd = fopen(fname,"a");
718: break;
719: case FILE_MODE_UPDATE:
720: vascii->fd = fopen(fname,"r+");
721: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
722: break;
723: case FILE_MODE_APPEND_UPDATE:
724: /* I really want a file which is opened at the end for updating,
725: not a+, which opens at the beginning, but makes writes at the end.
726: */
727: vascii->fd = fopen(fname,"r+");
728: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
729: else {
730: fseek(vascii->fd, 0, SEEK_END);
731: }
732: break;
733: default:
734: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
735: }
736: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
737: }
738: }
739: #if defined(PETSC_USE_LOG)
740: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
741: #endif
742: return(0);
743: }
747: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
748: {
749: PetscMPIInt rank;
750: PetscErrorCode ierr;
751: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
752: const char *name;
755: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
756: PetscViewerCreate(PETSC_COMM_SELF,outviewer);
757: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
758: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
759: ovascii->fd = vascii->fd;
760: ovascii->tab = vascii->tab;
762: vascii->sviewer = *outviewer;
764: (*outviewer)->format = viewer->format;
766: PetscObjectGetName((PetscObject)viewer,&name);
767: PetscObjectSetName((PetscObject)(*outviewer),name);
769: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
770: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
771: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
772: if (rank) (*outviewer)->ops->flush = 0;
773: else (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
774: return(0);
775: }
779: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
780: {
781: PetscErrorCode ierr;
782: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
783: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
786: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
787: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
789: ascii->sviewer = 0;
790: vascii->fd = PETSC_STDOUT;
791: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
792: PetscViewerDestroy(outviewer);
793: PetscViewerFlush(viewer);
794: return(0);
795: }
799: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
800: {
801: PetscErrorCode ierr;
802: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
803: const char *name;
806: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
807: /* Note that we need to open vascii->filename for the subcomm:
808: we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
809: Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
810: will return the current viewer, having increfed it.
811: */
812: PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
813: if (*outviewer == viewer) return(0);
814: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
816: ovascii->tab = vascii->tab;
817: vascii->sviewer = *outviewer;
819: (*outviewer)->format = viewer->format;
821: PetscObjectGetName((PetscObject)viewer,&name);
822: PetscObjectSetName((PetscObject)(*outviewer),name);
824: ((PetscViewer_ASCII*)((*outviewer)->data))->subviewer = viewer;
826: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
827: return(0);
828: }
832: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
833: {
834: PetscErrorCode ierr;
835: PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
836: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
839: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
840: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");
842: ascii->sviewer = 0;
843: oascii->fd = PETSC_STDOUT;
844: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
846: PetscViewerDestroy(outviewer);
847: PetscViewerFlush(viewer);
848: return(0);
849: }
853: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
854: {
855: PetscErrorCode ierr;
856: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
859: if (ascii->filename) {
860: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
861: }
862: return(0);
863: }
867: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
868: {
869: PetscViewer_ASCII *vascii;
870: PetscErrorCode ierr;
873: PetscNewLog(viewer,&vascii);
874: viewer->data = (void*)vascii;
876: viewer->ops->destroy = PetscViewerDestroy_ASCII;
877: viewer->ops->flush = PetscViewerFlush_ASCII;
878: viewer->ops->getsingleton = PetscViewerGetSingleton_ASCII;
879: viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
880: viewer->ops->getsubcomm = PetscViewerGetSubcomm_ASCII;
881: viewer->ops->restoresubcomm = PetscViewerRestoreSubcomm_ASCII;
882: viewer->ops->view = PetscViewerView_ASCII;
883: viewer->ops->read = PetscViewerASCIIRead;
885: /* defaults to stdout unless set with PetscViewerFileSetName() */
886: vascii->fd = PETSC_STDOUT;
887: vascii->mode = FILE_MODE_WRITE;
888: vascii->bviewer = 0;
889: vascii->subviewer = 0;
890: vascii->sviewer = 0;
891: vascii->tab = 0;
892: vascii->tab_store = 0;
893: vascii->filename = 0;
894: vascii->closefile = PETSC_TRUE;
896: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
897: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
898: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
899: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
900: return(0);
901: }
906: /*@C
907: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
908: several processors. Output of the first processor is followed by that of the
909: second, etc.
911: Not Collective, must call collective PetscViewerFlush() to get the results out
913: Input Parameters:
914: + viewer - the ASCII PetscViewer
915: - format - the usual printf() format string
917: Level: intermediate
919: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
921: Fortran Note:
922: Can only print a single character* string
924: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
925: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
926: PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()
928: @*/
929: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
930: {
931: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
932: PetscErrorCode ierr;
933: PetscMPIInt rank,size;
934: PetscInt tab = vascii->tab;
935: MPI_Comm comm;
936: FILE *fp;
937: PetscBool iascii;
938: int err;
943: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
944: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
945: MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);
946: if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
947: if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */
949: PetscObjectGetComm((PetscObject)viewer,&comm);
950: fp = vascii->fd;
951: MPI_Comm_rank(comm,&rank);
953: /* First processor prints immediately to fp */
954: if (!rank) {
955: va_list Argp;
957: while (tab--) {
958: PetscFPrintf(PETSC_COMM_SELF,fp," ");
959: }
961: va_start(Argp,format);
962: (*PetscVFPrintf)(fp,format,Argp);
963: err = fflush(fp);
964: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
965: if (petsc_history) {
966: va_start(Argp,format);
967: (*PetscVFPrintf)(petsc_history,format,Argp);
968: err = fflush(petsc_history);
969: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
970: }
971: va_end(Argp);
972: } else { /* other processors add to local queue */
973: char *string;
974: va_list Argp;
975: size_t fullLength;
976: PrintfQueue next;
978: PetscNew(&next);
979: if (petsc_printfqueue) {
980: petsc_printfqueue->next = next;
981: petsc_printfqueue = next;
982: } else {
983: petsc_printfqueuebase = petsc_printfqueue = next;
984: }
985: petsc_printfqueuelength++;
986: next->size = QUEUESTRINGSIZE;
987: PetscMalloc1(next->size, &next->string);
988: PetscMemzero(next->string,next->size);
989: string = next->string;
990: tab *= 2;
991: while (tab--) {
992: *string++ = ' ';
993: }
994: va_start(Argp,format);
995: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
996: va_end(Argp);
997: }
998: return(0);
999: }
1003: /*@C
1004: PetscViewerASCIIRead - Reads from am ASCII file
1006: Collective on MPI_Comm
1008: Input Parameters:
1009: + viewer - the ascii viewer
1010: . data - location to write the data
1011: . num - number of items of data to read
1012: - datatype - type of data to read
1014: Output Parameters:
1015: . count - number of items of data actually read, or NULL
1017: Level: beginner
1019: Concepts: ascii files
1021: .seealso: PetscViewerASCIIOpen(), PetscViewerSetFormat(), PetscViewerDestroy(),
1022: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1023: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1024: @*/
1025: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1026: {
1027: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1028: FILE *fd = vascii->fd;
1029: PetscInt i;
1030: int ret = 0;
1034: for (i=0; i<num; i++) {
1035: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1036: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1037: #if PETSC_USE_64BIT_INDICES
1038: #if (PETSC_SIZEOF_LONG_LONG == 8)
1039: else if (dtype == PETSC_INT) ret = fscanf(fd, "%ld", &(((PetscInt*)data)[i]));
1040: #else
1041: else if (dtype == PETSC_INT) ret = fscanf(fd, "%lld", &(((PetscInt*)data)[i]));
1042: #endif
1043: #else
1044: else if (dtype == PETSC_INT) ret = fscanf(fd, "%d", &(((PetscInt*)data)[i]));
1045: #endif
1046: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1047: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1048: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1049: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1050: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1051: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1052: }
1053: if (count) *count = i;
1054: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1055: return(0);
1056: }