Actual source code: filev.c
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>
4: #define QUEUESTRINGSIZE 8192
6: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
7: {
8: PetscMPIInt rank;
9: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
10: int err;
13: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
14: if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
15: if (vascii->fd && vascii->closefile) {
16: err = fclose(vascii->fd);
18: }
19: if (vascii->storecompressed) {
20: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
21: FILE *fp;
22: PetscStrncpy(par,"gzip ",sizeof(par));
23: PetscStrlcat(par,vascii->filename,sizeof(par));
24: #if defined(PETSC_HAVE_POPEN)
25: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
27: PetscPClose(PETSC_COMM_SELF,fp);
28: #else
29: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
30: #endif
31: }
32: }
33: PetscFree(vascii->filename);
34: return 0;
35: }
37: /* ----------------------------------------------------------------------*/
38: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
39: {
40: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
41: PetscViewerLink *vlink;
42: PetscBool flg;
45: PetscViewerFileClose_ASCII(viewer);
46: PetscFree(vascii);
48: /* remove the viewer from the list in the MPI Communicator */
49: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
50: MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
51: }
53: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
54: if (flg) {
55: if (vlink && vlink->viewer == viewer) {
56: if (vlink->next) {
57: MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
58: } else {
59: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
60: }
61: PetscFree(vlink);
62: } else {
63: while (vlink && vlink->next) {
64: if (vlink->next->viewer == viewer) {
65: PetscViewerLink *nv = vlink->next;
66: vlink->next = vlink->next->next;
67: PetscFree(nv);
68: }
69: vlink = vlink->next;
70: }
71: }
72: }
74: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
75: PetscViewer aviewer;
76: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
77: if (flg && aviewer == viewer) {
78: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
79: }
80: }
81: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
82: PetscViewer aviewer;
83: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
84: if (flg && aviewer == viewer) {
85: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
86: }
87: }
88: return 0;
89: }
91: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
92: {
93: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
95: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
96: return 0;
97: }
99: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
100: {
101: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
102: int err;
103: MPI_Comm comm;
104: PetscMPIInt rank,size;
105: FILE *fd = vascii->fd;
108: PetscObjectGetComm((PetscObject)viewer,&comm);
109: MPI_Comm_rank(comm,&rank);
110: MPI_Comm_size(comm,&size);
112: if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
113: err = fflush(vascii->fd);
115: }
117: if (vascii->allowsynchronized) {
118: PetscMPIInt tag,i,j,n = 0,dummy = 0;
119: char *message;
120: MPI_Status status;
122: PetscCommDuplicate(comm,&comm,&tag);
124: /* First processor waits for messages from all other processors */
125: if (rank == 0) {
126: /* flush my own messages that I may have queued up */
127: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
128: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
129: if (!vascii->bviewer) {
130: PetscFPrintf(comm,fd,"%s",next->string);
131: } else {
132: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
133: }
134: previous = next;
135: next = next->next;
136: PetscFree(previous->string);
137: PetscFree(previous);
138: }
139: vascii->petsc_printfqueue = NULL;
140: vascii->petsc_printfqueuelength = 0;
141: for (i=1; i<size; i++) {
142: /* to prevent a flood of messages to process zero, request each message separately */
143: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
144: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
145: for (j=0; j<n; j++) {
146: PetscMPIInt size = 0;
148: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
149: PetscMalloc1(size, &message);
150: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
151: if (!vascii->bviewer) {
152: PetscFPrintf(comm,fd,"%s",message);
153: } else {
154: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
155: }
156: PetscFree(message);
157: }
158: }
159: } else { /* other processors send queue to processor 0 */
160: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
162: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
163: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
164: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
165: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
166: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
167: previous = next;
168: next = next->next;
169: PetscFree(previous->string);
170: PetscFree(previous);
171: }
172: vascii->petsc_printfqueue = NULL;
173: vascii->petsc_printfqueuelength = 0;
174: }
175: PetscCommDestroy(&comm);
176: }
177: return 0;
178: }
180: /*@C
181: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
183: Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
185: Input Parameter:
186: . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
188: Output Parameter:
189: . fd - file pointer
191: Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
193: Level: intermediate
195: Fortran Note:
196: This routine is not supported in Fortran.
198: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
199: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
200: @*/
201: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
202: {
203: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
205: *fd = vascii->fd;
206: return 0;
207: }
209: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
210: {
211: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
213: *mode = vascii->mode;
214: return 0;
215: }
217: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
218: {
219: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
221: vascii->mode = mode;
222: return 0;
223: }
225: /*
226: If petsc_history is on, then all Petsc*Printf() results are saved
227: if the appropriate (usually .petschistory) file.
228: */
229: PETSC_INTERN FILE *petsc_history;
231: /*@
232: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
234: Not Collective, but only first processor in set has any effect
236: Input Parameters:
237: + viewer - obtained with PetscViewerASCIIOpen()
238: - tabs - number of tabs
240: Level: developer
242: Fortran Note:
243: This routine is not supported in Fortran.
245: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
246: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
247: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
248: @*/
249: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
250: {
251: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
252: PetscBool iascii;
255: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
256: if (iascii) ascii->tab = tabs;
257: return 0;
258: }
260: /*@
261: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
263: Not Collective, meaningful on first processor only.
265: Input Parameters:
266: . viewer - obtained with PetscViewerASCIIOpen()
268: Output Parameters:
269: . tabs - number of tabs
271: Level: developer
273: Fortran Note:
274: This routine is not supported in Fortran.
276: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
277: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
278: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
279: @*/
280: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
281: {
282: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
283: PetscBool iascii;
286: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
287: if (iascii && tabs) *tabs = ascii->tab;
288: return 0;
289: }
291: /*@
292: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
294: Not Collective, but only first processor in set has any effect
296: Input Parameters:
297: + viewer - obtained with PetscViewerASCIIOpen()
298: - tabs - number of tabs
300: Level: developer
302: Fortran Note:
303: This routine is not supported in Fortran.
305: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
306: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
307: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
308: @*/
309: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
310: {
311: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
312: PetscBool iascii;
315: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
316: if (iascii) ascii->tab += tabs;
317: return 0;
318: }
320: /*@
321: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
323: Not Collective, but only first processor in set has any effect
325: Input Parameters:
326: + viewer - obtained with PetscViewerASCIIOpen()
327: - tabs - number of tabs
329: Level: developer
331: Fortran Note:
332: This routine is not supported in Fortran.
334: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
335: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
336: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
337: @*/
338: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
339: {
340: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
341: PetscBool iascii;
344: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
345: if (iascii) ascii->tab -= tabs;
346: return 0;
347: }
349: /*@C
350: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
352: Collective on PetscViewer
354: Input Parameters:
355: . viewer - obtained with PetscViewerASCIIOpen()
357: Level: intermediate
359: Notes:
360: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
362: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
363: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
364: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
365: @*/
366: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
367: {
368: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
369: PetscBool iascii;
373: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
374: if (iascii) ascii->allowsynchronized++;
375: return 0;
376: }
378: /*@C
379: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
381: Collective on PetscViewer
383: Input Parameters:
384: . viewer - obtained with PetscViewerASCIIOpen()
386: Level: intermediate
388: Notes:
389: See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
391: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
392: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
393: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
394: @*/
395: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
396: {
397: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
398: PetscBool iascii;
402: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
403: if (iascii) {
404: ascii->allowsynchronized--;
406: }
407: return 0;
408: }
410: /*@C
411: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
412: lines are tabbed.
414: Not Collective, but only first processor in set has any effect
416: Input Parameters:
417: . viewer - obtained with PetscViewerASCIIOpen()
419: Level: developer
421: Fortran Note:
422: This routine is not supported in Fortran.
424: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
425: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
426: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
427: @*/
428: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
429: {
430: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
431: PetscBool iascii;
434: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
435: if (iascii) ascii->tab++;
436: return 0;
437: }
439: /*@C
440: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
441: lines are tabbed.
443: Not Collective, but only first processor in set has any effect
445: Input Parameters:
446: . viewer - obtained with PetscViewerASCIIOpen()
448: Level: developer
450: Fortran Note:
451: This routine is not supported in Fortran.
453: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
454: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
455: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
456: @*/
457: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
458: {
459: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
460: PetscBool iascii;
463: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
464: if (iascii) {
466: ascii->tab--;
467: }
468: return 0;
469: }
471: /*@
472: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
474: Not Collective, but only first processor in set has any effect
476: Input Parameters:
477: + viewer - obtained with PetscViewerASCIIOpen()
478: - flg - PETSC_TRUE or PETSC_FALSE
480: Level: developer
482: Fortran Note:
483: This routine is not supported in Fortran.
485: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
486: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
487: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
488: @*/
489: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
490: {
491: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
492: PetscBool iascii;
495: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
496: if (iascii) {
497: if (flg) ascii->tab = ascii->tab_store;
498: else {
499: ascii->tab_store = ascii->tab;
500: ascii->tab = 0;
501: }
502: }
503: return 0;
504: }
506: /* ----------------------------------------------------------------------- */
508: /*@C
509: PetscViewerASCIIPrintf - Prints to a file, only from the first
510: processor in the PetscViewer
512: Not Collective, but only first processor in set has any effect
514: Input Parameters:
515: + viewer - obtained with PetscViewerASCIIOpen()
516: - format - the usual printf() format string
518: Level: developer
520: Fortran Note:
521: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
522: That is, you can only pass a single character string from Fortran.
524: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
525: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
526: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
527: @*/
528: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
529: {
530: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
531: PetscMPIInt rank;
532: PetscInt tab,intab = ascii->tab;
533: FILE *fd = ascii->fd;
534: PetscBool iascii;
535: int err;
540: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
542: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
543: if (rank) return 0;
545: if (ascii->bviewer) { /* pass string up to parent viewer */
546: char *string;
547: va_list Argp;
548: size_t fullLength;
550: PetscCalloc1(QUEUESTRINGSIZE, &string);
551: va_start(Argp,format);
552: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
553: va_end(Argp);
554: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
555: PetscFree(string);
556: } else { /* write directly to file */
557: va_list Argp;
558: /* flush my own messages that I may have queued up */
559: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
560: PetscInt i;
561: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
562: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
563: previous = next;
564: next = next->next;
565: PetscFree(previous->string);
566: PetscFree(previous);
567: }
568: ascii->petsc_printfqueue = NULL;
569: ascii->petsc_printfqueuelength = 0;
570: tab = intab;
571: while (tab--) {
572: PetscFPrintf(PETSC_COMM_SELF,fd," ");
573: }
575: va_start(Argp,format);
576: (*PetscVFPrintf)(fd,format,Argp);
577: err = fflush(fd);
579: if (petsc_history) {
580: va_start(Argp,format);
581: tab = intab;
582: while (tab--) {
583: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
584: }
585: (*PetscVFPrintf)(petsc_history,format,Argp);
586: err = fflush(petsc_history);
588: }
589: va_end(Argp);
590: }
591: return 0;
592: }
594: /*@C
595: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
597: Collective on PetscViewer
599: Input Parameters:
600: + viewer - the PetscViewer; either ASCII or binary
601: - name - the name of the file it should use
603: Level: advanced
605: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
606: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
608: @*/
609: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
610: {
611: char filename[PETSC_MAX_PATH_LEN];
615: PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
616: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
617: return 0;
618: }
620: /*@C
621: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
623: Not Collective
625: Input Parameter:
626: . viewer - the PetscViewer; either ASCII or binary
628: Output Parameter:
629: . name - the name of the file it is using
631: Level: advanced
633: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
635: @*/
636: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
637: {
640: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
641: return 0;
642: }
644: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
645: {
646: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
648: *name = vascii->filename;
649: return 0;
650: }
652: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
653: {
654: size_t len;
655: char fname[PETSC_MAX_PATH_LEN],*gz;
656: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
657: PetscBool isstderr,isstdout;
658: PetscMPIInt rank;
660: PetscViewerFileClose_ASCII(viewer);
661: if (!name) return 0;
662: PetscStrallocpy(name,&vascii->filename);
664: /* Is this file to be compressed */
665: vascii->storecompressed = PETSC_FALSE;
667: PetscStrstr(vascii->filename,".gz",&gz);
668: if (gz) {
669: PetscStrlen(gz,&len);
670: if (len == 3) {
672: *gz = 0;
673: vascii->storecompressed = PETSC_TRUE;
674: }
675: }
676: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
677: if (rank == 0) {
678: PetscStrcmp(name,"stderr",&isstderr);
679: PetscStrcmp(name,"stdout",&isstdout);
680: /* empty filename means stdout */
681: if (name[0] == 0) isstdout = PETSC_TRUE;
682: if (isstderr) vascii->fd = PETSC_STDERR;
683: else if (isstdout) vascii->fd = PETSC_STDOUT;
684: else {
686: PetscFixFilename(name,fname);
687: switch (vascii->mode) {
688: case FILE_MODE_READ:
689: vascii->fd = fopen(fname,"r");
690: break;
691: case FILE_MODE_WRITE:
692: vascii->fd = fopen(fname,"w");
693: break;
694: case FILE_MODE_APPEND:
695: vascii->fd = fopen(fname,"a");
696: break;
697: case FILE_MODE_UPDATE:
698: vascii->fd = fopen(fname,"r+");
699: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
700: break;
701: case FILE_MODE_APPEND_UPDATE:
702: /* I really want a file which is opened at the end for updating,
703: not a+, which opens at the beginning, but makes writes at the end.
704: */
705: vascii->fd = fopen(fname,"r+");
706: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
707: else {
708: fseek(vascii->fd, 0, SEEK_END);
709: }
710: break;
711: default:
712: SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
713: }
715: }
716: }
717: #if defined(PETSC_USE_LOG)
718: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
719: #endif
720: return 0;
721: }
723: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
724: {
725: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
727: PetscViewerASCIIPushSynchronized(viewer);
729: /*
730: The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
731: because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
732: (since the count never gets to zero) in some examples this displays information that otherwise would be lost
734: This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
735: PCView_GASM().
736: */
737: PetscViewerASCIIPushSynchronized(viewer);
738: PetscViewerCreate(subcomm,outviewer);
739: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
740: PetscViewerASCIIPushSynchronized(*outviewer);
741: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
742: ovascii->fd = vascii->fd;
743: ovascii->tab = vascii->tab;
744: ovascii->closefile = PETSC_FALSE;
746: vascii->sviewer = *outviewer;
747: (*outviewer)->format = viewer->format;
748: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
749: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
750: return 0;
751: }
753: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
754: {
755: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
760: PetscViewerASCIIPopSynchronized(*outviewer);
761: ascii->sviewer = NULL;
762: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
763: PetscViewerDestroy(outviewer);
764: PetscViewerASCIIPopSynchronized(viewer);
765: return 0;
766: }
768: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
769: {
770: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
772: if (ascii->filename) {
773: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
774: }
775: return 0;
776: }
778: /*MC
779: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
781: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
782: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
783: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
785: Level: beginner
787: M*/
788: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
789: {
790: PetscViewer_ASCII *vascii;
792: PetscNewLog(viewer,&vascii);
793: viewer->data = (void*)vascii;
795: viewer->ops->destroy = PetscViewerDestroy_ASCII;
796: viewer->ops->flush = PetscViewerFlush_ASCII;
797: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
798: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
799: viewer->ops->view = PetscViewerView_ASCII;
800: viewer->ops->read = PetscViewerASCIIRead;
802: /* defaults to stdout unless set with PetscViewerFileSetName() */
803: vascii->fd = PETSC_STDOUT;
804: vascii->mode = FILE_MODE_WRITE;
805: vascii->bviewer = NULL;
806: vascii->subviewer = NULL;
807: vascii->sviewer = NULL;
808: vascii->tab = 0;
809: vascii->tab_store = 0;
810: vascii->filename = NULL;
811: vascii->closefile = PETSC_TRUE;
813: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
814: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
815: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
816: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
817: return 0;
818: }
820: /*@C
821: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
822: several processors. Output of the first processor is followed by that of the
823: second, etc.
825: Not Collective, must call collective PetscViewerFlush() to get the results out
827: Input Parameters:
828: + viewer - the ASCII PetscViewer
829: - format - the usual printf() format string
831: Level: intermediate
833: Notes:
834: You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
835: Then you can do multiple independent calls to this routine.
836: The actual synchronized print is then done using PetscViewerFlush().
837: PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
838: to conclude the "synchronized session".
839: So the typical calling sequence looks like
840: $ PetscViewerASCIIPushSynchronized(viewer);
841: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
842: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
843: $ ...
844: $ PetscViewerFlush(viewer);
845: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
846: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
847: $ ...
848: $ PetscViewerFlush(viewer);
849: $ PetscViewerASCIIPopSynchronized(viewer);
851: Fortran Note:
852: Can only print a single character* string
854: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
855: PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
856: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
857: @*/
858: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
859: {
860: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
861: PetscMPIInt rank;
862: PetscInt tab = vascii->tab;
863: MPI_Comm comm;
864: FILE *fp;
865: PetscBool iascii,hasbviewer = PETSC_FALSE;
866: int err;
870: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
874: PetscObjectGetComm((PetscObject)viewer,&comm);
875: MPI_Comm_rank(comm,&rank);
877: if (vascii->bviewer) {
878: hasbviewer = PETSC_TRUE;
879: if (rank == 0) {
880: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
881: PetscObjectGetComm((PetscObject)viewer,&comm);
882: MPI_Comm_rank(comm,&rank);
883: }
884: }
886: fp = vascii->fd;
888: if (rank == 0 && !hasbviewer) { /* First processor prints immediately to fp */
889: va_list Argp;
890: /* flush my own messages that I may have queued up */
891: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
892: PetscInt i;
893: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
894: PetscFPrintf(comm,fp,"%s",next->string);
895: previous = next;
896: next = next->next;
897: PetscFree(previous->string);
898: PetscFree(previous);
899: }
900: vascii->petsc_printfqueue = NULL;
901: vascii->petsc_printfqueuelength = 0;
903: while (tab--) {
904: PetscFPrintf(PETSC_COMM_SELF,fp," ");
905: }
907: va_start(Argp,format);
908: (*PetscVFPrintf)(fp,format,Argp);
909: err = fflush(fp);
911: if (petsc_history) {
912: va_start(Argp,format);
913: (*PetscVFPrintf)(petsc_history,format,Argp);
914: err = fflush(petsc_history);
916: }
917: va_end(Argp);
918: } else { /* other processors add to queue */
919: char *string;
920: va_list Argp;
921: size_t fullLength;
922: PrintfQueue next;
924: PetscNew(&next);
925: if (vascii->petsc_printfqueue) {
926: vascii->petsc_printfqueue->next = next;
927: vascii->petsc_printfqueue = next;
928: } else {
929: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
930: }
931: vascii->petsc_printfqueuelength++;
932: next->size = QUEUESTRINGSIZE;
933: PetscCalloc1(next->size, &next->string);
934: string = next->string;
935: tab *= 2;
936: while (tab--) {
937: *string++ = ' ';
938: }
939: va_start(Argp,format);
940: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
941: va_end(Argp);
942: if (fullLength > (size_t) (next->size-2*vascii->tab)) {
943: PetscFree(next->string);
944: next->size = fullLength + 2*vascii->tab;
945: PetscCalloc1(next->size, &next->string);
946: string = next->string;
947: tab = 2*vascii->tab;
948: while (tab--) {
949: *string++ = ' ';
950: }
951: va_start(Argp,format);
952: PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
953: va_end(Argp);
954: }
955: }
956: return 0;
957: }
959: /*@C
960: PetscViewerASCIIRead - Reads from a ASCII file
962: Only process 0 in the PetscViewer may call this
964: Input Parameters:
965: + viewer - the ascii viewer
966: . data - location to write the data
967: . num - number of items of data to read
968: - datatype - type of data to read
970: Output Parameters:
971: . count - number of items of data actually read, or NULL
973: Level: beginner
975: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
976: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
977: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
978: @*/
979: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
980: {
981: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
982: FILE *fd = vascii->fd;
983: PetscInt i;
984: int ret = 0;
985: PetscMPIInt rank;
988: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
990: for (i=0; i<num; i++) {
991: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
992: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
993: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
994: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
995: else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i]));
996: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i]));
997: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
998: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
999: #if defined(PETSC_USE_REAL___FLOAT128)
1000: else if (dtype == PETSC___FLOAT128) {
1001: double tmp;
1002: ret = fscanf(fd, "%lg", &tmp);
1003: ((__float128*)data)[i] = tmp;
1004: }
1005: #endif
1006: else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1008: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1009: }
1010: if (count) *count = i;
1012: return 0;
1013: }