Actual source code: filev.c
petsc-3.7.7 2017-09-25
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_SubViewer(PetscViewer viewer)
86: {
87: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
88: PetscErrorCode ierr;
91: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
92: return(0);
93: }
97: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
98: {
99: PetscErrorCode ierr;
100: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
101: int err;
102: MPI_Comm comm;
103: PetscMPIInt rank,size;
104: FILE *fd = vascii->fd;
107: PetscObjectGetComm((PetscObject)viewer,&comm);
108: MPI_Comm_rank(comm,&rank);
109: MPI_Comm_size(comm,&size);
111: if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
112: err = fflush(vascii->fd);
113: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
114: }
116: if (vascii->allowsynchronized) {
117: PetscMPIInt tag,i,j,n = 0,dummy = 0;
118: char *message;
119: MPI_Status status;
121: PetscCommDuplicate(comm,&comm,&tag);
123: /* First processor waits for messages from all other processors */
124: if (!rank) {
125: /* flush my own messages that I may have queued up */
126: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
127: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
128: if (!vascii->bviewer) {
129: PetscFPrintf(comm,fd,"%s",next->string);
130: } else {
131: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
132: }
133: previous = next;
134: next = next->next;
135: PetscFree(previous->string);
136: PetscFree(previous);
137: }
138: vascii->petsc_printfqueue = 0;
139: vascii->petsc_printfqueuelength = 0;
140: for (i=1; i<size; i++) {
141: /* to prevent a flood of messages to process zero, request each message separately */
142: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
143: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
144: for (j=0; j<n; j++) {
145: PetscMPIInt size = 0;
147: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
148: PetscMalloc1(size, &message);
149: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
150: if (!vascii->bviewer) {
151: PetscFPrintf(comm,fd,"%s",message);
152: } else {
153: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
154: }
155: PetscFree(message);
156: }
157: }
158: } else { /* other processors send queue to processor 0 */
159: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
161: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
162: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
163: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
164: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
165: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
166: previous = next;
167: next = next->next;
168: PetscFree(previous->string);
169: PetscFree(previous);
170: }
171: vascii->petsc_printfqueue = 0;
172: vascii->petsc_printfqueuelength = 0;
173: }
174: PetscCommDestroy(&comm);
175: }
176: return(0);
177: }
181: /*@C
182: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
184: Not Collective
186: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
187: - fd - file pointer
189: Level: intermediate
191: Fortran Note:
192: This routine is not supported in Fortran.
194: Concepts: PetscViewer^file pointer
195: Concepts: file pointer^getting from PetscViewer
197: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
198: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
199: @*/
200: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
201: {
202: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
205: *fd = vascii->fd;
206: return(0);
207: }
211: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
212: {
213: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
216: *mode = vascii->mode;
217: return(0);
218: }
222: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
223: {
224: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
227: vascii->mode = mode;
228: return(0);
229: }
231: /*
232: If petsc_history is on, then all Petsc*Printf() results are saved
233: if the appropriate (usually .petschistory) file.
234: */
235: extern FILE *petsc_history;
239: /*@
240: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
242: Not Collective, but only first processor in set has any effect
244: Input Parameters:
245: + viewer - obtained with PetscViewerASCIIOpen()
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^setting
256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
257: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259: @*/
260: PetscErrorCode PetscViewerASCIISetTab(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) ascii->tab = tabs;
270: return(0);
271: }
275: /*@
276: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
278: Not Collective, meaningful on first processor only.
280: Input Parameters:
281: . viewer - obtained with PetscViewerASCIIOpen()
282: Output Parameters:
283: . tabs - number of tabs
285: Level: developer
287: Fortran Note:
288: This routine is not supported in Fortran.
290: Concepts: PetscViewerASCII^formating
291: Concepts: tab^retrieval
293: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
294: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
295: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
296: @*/
297: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
298: {
299: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
300: PetscBool iascii;
301: PetscErrorCode ierr;
305: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
306: if (iascii && tabs) *tabs = ascii->tab;
307: return(0);
308: }
312: /*@
313: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
315: Not Collective, but only first processor in set has any effect
317: Input Parameters:
318: + viewer - obtained with PetscViewerASCIIOpen()
319: - tabs - number of tabs
321: Level: developer
323: Fortran Note:
324: This routine is not supported in Fortran.
326: Concepts: PetscViewerASCII^formating
327: Concepts: tab^setting
329: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
330: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
331: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
332: @*/
333: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
334: {
335: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
336: PetscBool iascii;
337: PetscErrorCode ierr;
341: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
342: if (iascii) ascii->tab += tabs;
343: return(0);
344: }
348: /*@
349: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
351: Not Collective, but only first processor in set has any effect
353: Input Parameters:
354: + viewer - obtained with PetscViewerASCIIOpen()
355: - tabs - number of tabs
357: Level: developer
359: Fortran Note:
360: This routine is not supported in Fortran.
362: Concepts: PetscViewerASCII^formating
363: Concepts: tab^setting
365: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
366: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
367: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
368: @*/
369: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
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->tab -= tabs;
379: return(0);
380: }
384: /*@C
385: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
387: Collective on PetscViewer
389: Input Parameters:
390: . viewer - obtained with PetscViewerASCIIOpen()
392: Level: intermediate
394: Concepts: PetscViewerASCII^formating
395: Concepts: tab^setting
397: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
398: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
399: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
400: @*/
401: PetscErrorCode PetscViewerASCIIPushSynchronized(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->allowsynchronized++;
411: return(0);
412: }
416: /*@C
417: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
419: Collective on PetscViewer
421: Input Parameters:
422: . viewer - obtained with PetscViewerASCIIOpen()
424: Level: intermediate
426: Concepts: PetscViewerASCII^formating
427: Concepts: tab^setting
429: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
430: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
431: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
432: @*/
433: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
434: {
435: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
436: PetscBool iascii;
437: PetscErrorCode ierr;
441: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
442: if (iascii) {
443: ascii->allowsynchronized--;
444: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
445: }
446: return(0);
447: }
451: /*@
452: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
453: lines are tabbed.
455: Not Collective, but only first processor in set has any effect
457: Input Parameters:
458: . viewer - obtained with PetscViewerASCIIOpen()
460: Level: developer
462: Fortran Note:
463: This routine is not supported in Fortran.
465: Concepts: PetscViewerASCII^formating
466: Concepts: tab^setting
468: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
469: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
470: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
471: @*/
472: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
473: {
474: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
475: PetscBool iascii;
476: PetscErrorCode ierr;
480: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
481: if (iascii) ascii->tab++;
482: return(0);
483: }
487: /*@
488: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
489: lines are tabbed.
491: Not Collective, but only first processor in set has any effect
493: Input Parameters:
494: . viewer - obtained with PetscViewerASCIIOpen()
496: Level: developer
498: Fortran Note:
499: This routine is not supported in Fortran.
501: Concepts: PetscViewerASCII^formating
502: Concepts: tab^setting
504: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
505: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
506: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
507: @*/
508: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
509: {
510: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
511: PetscErrorCode ierr;
512: PetscBool iascii;
516: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
517: if (iascii) {
518: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
519: ascii->tab--;
520: }
521: return(0);
522: }
526: /*@
527: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
529: Not Collective, but only first processor in set has any effect
531: Input Parameters:
532: + viewer - obtained with PetscViewerASCIIOpen()
533: - flg - PETSC_TRUE or PETSC_FALSE
535: Level: developer
537: Fortran Note:
538: This routine is not supported in Fortran.
540: Concepts: PetscViewerASCII^formating
541: Concepts: tab^setting
543: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
544: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
545: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
546: @*/
547: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
548: {
549: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
550: PetscBool iascii;
551: PetscErrorCode ierr;
555: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
556: if (iascii) {
557: if (flg) ascii->tab = ascii->tab_store;
558: else {
559: ascii->tab_store = ascii->tab;
560: ascii->tab = 0;
561: }
562: }
563: return(0);
564: }
566: /* ----------------------------------------------------------------------- */
571: /*@C
572: PetscViewerASCIIPrintf - Prints to a file, only from the first
573: processor in the PetscViewer
575: Not Collective, but only first processor in set has any effect
577: Input Parameters:
578: + viewer - obtained with PetscViewerASCIIOpen()
579: - format - the usual printf() format string
581: Level: developer
583: Fortran Note:
584: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
585: That is, you can only pass a single character string from Fortran.
587: Concepts: PetscViewerASCII^printing
588: Concepts: printing^to file
589: Concepts: printf
591: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
592: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
593: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
594: @*/
595: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
596: {
597: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
598: PetscMPIInt rank;
599: PetscInt tab,intab = ascii->tab;
600: PetscErrorCode ierr;
601: FILE *fd = ascii->fd;
602: PetscBool iascii;
603: int err;
608: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
609: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
610: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
611: if (rank) return(0);
613: if (ascii->bviewer) { /* pass string up to parent viewer */
614: char *string;
615: va_list Argp;
616: size_t fullLength;
618: PetscCalloc1(QUEUESTRINGSIZE, &string);
619: va_start(Argp,format);
620: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
621: va_end(Argp);
622: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
623: PetscFree(string);
624: } else { /* write directly to file */
625: va_list Argp;
626: /* flush my own messages that I may have queued up */
627: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
628: PetscInt i;
629: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
630: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
631: previous = next;
632: next = next->next;
633: PetscFree(previous->string);
634: PetscFree(previous);
635: }
636: ascii->petsc_printfqueue = 0;
637: ascii->petsc_printfqueuelength = 0;
638: tab = intab;
639: while (tab--) {
640: PetscFPrintf(PETSC_COMM_SELF,fd," ");
641: }
643: va_start(Argp,format);
644: (*PetscVFPrintf)(fd,format,Argp);
645: err = fflush(fd);
646: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
647: if (petsc_history) {
648: va_start(Argp,format);
649: tab = intab;
650: while (tab--) {
651: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
652: }
653: (*PetscVFPrintf)(petsc_history,format,Argp);
654: err = fflush(petsc_history);
655: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
656: }
657: va_end(Argp);
658: }
659: return(0);
660: }
664: /*@C
665: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
667: Collective on PetscViewer
669: Input Parameters:
670: + viewer - the PetscViewer; either ASCII or binary
671: - name - the name of the file it should use
673: Level: advanced
675: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
676: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
678: @*/
679: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
680: {
686: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
687: return(0);
688: }
692: /*@C
693: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
695: Not Collective
697: Input Parameter:
698: . viewer - the PetscViewer; either ASCII or binary
700: Output Parameter:
701: . name - the name of the file it is using
703: Level: advanced
705: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
707: @*/
708: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
709: {
714: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
715: return(0);
716: }
720: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
721: {
722: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
725: *name = vascii->filename;
726: return(0);
727: }
731: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
732: {
733: PetscErrorCode ierr;
734: size_t len;
735: char fname[PETSC_MAX_PATH_LEN],*gz;
736: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
737: PetscBool isstderr,isstdout;
738: PetscMPIInt rank;
741: PetscViewerFileClose_ASCII(viewer);
742: if (!name) return(0);
743: PetscStrallocpy(name,&vascii->filename);
745: /* Is this file to be compressed */
746: vascii->storecompressed = PETSC_FALSE;
748: PetscStrstr(vascii->filename,".gz",&gz);
749: if (gz) {
750: PetscStrlen(gz,&len);
751: if (len == 3) {
752: *gz = 0;
753: vascii->storecompressed = PETSC_TRUE;
754: }
755: }
756: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
757: if (!rank) {
758: PetscStrcmp(name,"stderr",&isstderr);
759: PetscStrcmp(name,"stdout",&isstdout);
760: /* empty filename means stdout */
761: if (name[0] == 0) isstdout = PETSC_TRUE;
762: if (isstderr) vascii->fd = PETSC_STDERR;
763: else if (isstdout) vascii->fd = PETSC_STDOUT;
764: else {
767: PetscFixFilename(name,fname);
768: switch (vascii->mode) {
769: case FILE_MODE_READ:
770: vascii->fd = fopen(fname,"r");
771: break;
772: case FILE_MODE_WRITE:
773: vascii->fd = fopen(fname,"w");
774: break;
775: case FILE_MODE_APPEND:
776: vascii->fd = fopen(fname,"a");
777: break;
778: case FILE_MODE_UPDATE:
779: vascii->fd = fopen(fname,"r+");
780: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
781: break;
782: case FILE_MODE_APPEND_UPDATE:
783: /* I really want a file which is opened at the end for updating,
784: not a+, which opens at the beginning, but makes writes at the end.
785: */
786: vascii->fd = fopen(fname,"r+");
787: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
788: else {
789: fseek(vascii->fd, 0, SEEK_END);
790: }
791: break;
792: default:
793: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
794: }
795: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
796: }
797: }
798: #if defined(PETSC_USE_LOG)
799: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
800: #endif
801: return(0);
802: }
806: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
807: {
808: PetscMPIInt rank;
809: PetscErrorCode ierr;
810: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
813: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
814: PetscViewerASCIIPushSynchronized(viewer);
815: PetscViewerCreate(subcomm,outviewer);
816: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
817: PetscViewerASCIIPushSynchronized(*outviewer);
818: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
819: ovascii->fd = vascii->fd;
820: ovascii->tab = vascii->tab;
821: ovascii->closefile = PETSC_FALSE;
823: vascii->sviewer = *outviewer;
825: (*outviewer)->format = viewer->format;
827: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
828: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
829: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
830: return(0);
831: }
835: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
836: {
837: PetscErrorCode ierr;
838: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
841: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
842: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
844: ascii->sviewer = 0;
845: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
846: PetscViewerDestroy(outviewer);
847: return(0);
848: }
852: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
853: {
854: PetscErrorCode ierr;
855: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
858: if (ascii->filename) {
859: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
860: }
861: return(0);
862: }
866: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
867: {
868: PetscViewer_ASCII *vascii;
869: PetscErrorCode ierr;
872: PetscNewLog(viewer,&vascii);
873: viewer->data = (void*)vascii;
875: viewer->ops->destroy = PetscViewerDestroy_ASCII;
876: viewer->ops->flush = PetscViewerFlush_ASCII;
877: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
878: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
879: viewer->ops->view = PetscViewerView_ASCII;
880: viewer->ops->read = PetscViewerASCIIRead;
882: /* defaults to stdout unless set with PetscViewerFileSetName() */
883: vascii->fd = PETSC_STDOUT;
884: vascii->mode = FILE_MODE_WRITE;
885: vascii->bviewer = 0;
886: vascii->subviewer = 0;
887: vascii->sviewer = 0;
888: vascii->tab = 0;
889: vascii->tab_store = 0;
890: vascii->filename = 0;
891: vascii->closefile = PETSC_TRUE;
893: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
894: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
895: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
896: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
897: return(0);
898: }
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(), PetscViewerASCIIPushSynchronized()
924: @*/
925: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
926: {
927: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
928: PetscErrorCode ierr;
929: PetscMPIInt rank;
930: PetscInt tab = vascii->tab;
931: MPI_Comm comm;
932: FILE *fp;
933: PetscBool iascii,hasbviewer = PETSC_FALSE;
934: int err;
939: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
940: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
941: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
943: PetscObjectGetComm((PetscObject)viewer,&comm);
944: MPI_Comm_rank(comm,&rank);
946: if (vascii->bviewer) {
947: hasbviewer = PETSC_TRUE;
948: if (!rank) {
949: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
950: PetscObjectGetComm((PetscObject)viewer,&comm);
951: MPI_Comm_rank(comm,&rank);
952: }
953: }
955: fp = vascii->fd;
957: if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
958: va_list Argp;
959: /* flush my own messages that I may have queued up */
960: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
961: PetscInt i;
962: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
963: PetscFPrintf(comm,fp,"%s",next->string);
964: previous = next;
965: next = next->next;
966: PetscFree(previous->string);
967: PetscFree(previous);
968: }
969: vascii->petsc_printfqueue = 0;
970: vascii->petsc_printfqueuelength = 0;
972: while (tab--) {
973: PetscFPrintf(PETSC_COMM_SELF,fp," ");
974: }
976: va_start(Argp,format);
977: (*PetscVFPrintf)(fp,format,Argp);
978: err = fflush(fp);
979: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
980: if (petsc_history) {
981: va_start(Argp,format);
982: (*PetscVFPrintf)(petsc_history,format,Argp);
983: err = fflush(petsc_history);
984: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
985: }
986: va_end(Argp);
987: } else { /* other processors add to queue */
988: char *string;
989: va_list Argp;
990: size_t fullLength;
991: PrintfQueue next;
993: PetscNew(&next);
994: if (vascii->petsc_printfqueue) {
995: vascii->petsc_printfqueue->next = next;
996: vascii->petsc_printfqueue = next;
997: } else {
998: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
999: }
1000: vascii->petsc_printfqueuelength++;
1001: next->size = QUEUESTRINGSIZE;
1002: PetscMalloc1(next->size, &next->string);
1003: PetscMemzero(next->string,next->size);
1004: string = next->string;
1005: tab *= 2;
1006: while (tab--) {
1007: *string++ = ' ';
1008: }
1009: va_start(Argp,format);
1010: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1011: va_end(Argp);
1012: }
1013: return(0);
1014: }
1018: /*@C
1019: PetscViewerASCIIRead - Reads from am ASCII file
1021: Collective on MPI_Comm
1023: Input Parameters:
1024: + viewer - the ascii viewer
1025: . data - location to write the data
1026: . num - number of items of data to read
1027: - datatype - type of data to read
1029: Output Parameters:
1030: . count - number of items of data actually read, or NULL
1032: Level: beginner
1034: Concepts: ascii files
1036: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1037: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1038: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1039: @*/
1040: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1041: {
1042: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1043: FILE *fd = vascii->fd;
1044: PetscInt i;
1045: int ret = 0;
1049: for (i=0; i<num; i++) {
1050: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1051: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1052: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1053: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1054: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1055: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1056: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1057: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1058: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1059: }
1060: if (count) *count = i;
1061: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1062: return(0);
1063: }