Actual source code: filev.c
petsc-3.8.0 2017-09-26
2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>
4: #define QUEUESTRINGSIZE 8192
6: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
7: {
8: PetscErrorCode ierr;
9: PetscMPIInt rank;
10: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
11: int err;
14: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
15: if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
16: if (vascii->fd && vascii->closefile) {
17: err = fclose(vascii->fd);
18: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
19: }
20: if (vascii->storecompressed) {
21: char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
22: FILE *fp;
23: PetscStrcpy(par,"gzip ");
24: PetscStrcat(par,vascii->filename);
25: #if defined(PETSC_HAVE_POPEN)
26: PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
27: if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
28: PetscPClose(PETSC_COMM_SELF,fp,NULL);
29: #else
30: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
31: #endif
32: }
33: }
34: PetscFree(vascii->filename);
35: return(0);
36: }
38: /* ----------------------------------------------------------------------*/
39: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
40: {
41: PetscErrorCode ierr;
42: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
43: PetscViewerLink *vlink;
44: PetscBool flg;
47: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
48: PetscViewerFileClose_ASCII(viewer);
49: PetscFree(vascii);
51: /* remove the viewer from the list in the MPI Communicator */
52: if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
53: MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
54: }
56: MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
57: if (flg) {
58: if (vlink && vlink->viewer == viewer) {
59: if (vlink->next) {
60: MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
61: } else {
62: MPI_Attr_delete(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
63: }
64: PetscFree(vlink);
65: } else {
66: while (vlink && vlink->next) {
67: if (vlink->next->viewer == viewer) {
68: PetscViewerLink *nv = vlink->next;
69: vlink->next = vlink->next->next;
70: PetscFree(nv);
71: }
72: vlink = vlink->next;
73: }
74: }
75: }
76: return(0);
77: }
79: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
80: {
81: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
82: PetscErrorCode ierr;
85: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
86: return(0);
87: }
89: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
90: {
91: PetscErrorCode ierr;
92: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
93: int err;
94: MPI_Comm comm;
95: PetscMPIInt rank,size;
96: FILE *fd = vascii->fd;
99: PetscObjectGetComm((PetscObject)viewer,&comm);
100: MPI_Comm_rank(comm,&rank);
101: MPI_Comm_size(comm,&size);
103: if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
104: err = fflush(vascii->fd);
105: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
106: }
108: if (vascii->allowsynchronized) {
109: PetscMPIInt tag,i,j,n = 0,dummy = 0;
110: char *message;
111: MPI_Status status;
113: PetscCommDuplicate(comm,&comm,&tag);
115: /* First processor waits for messages from all other processors */
116: if (!rank) {
117: /* flush my own messages that I may have queued up */
118: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
119: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
120: if (!vascii->bviewer) {
121: PetscFPrintf(comm,fd,"%s",next->string);
122: } else {
123: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
124: }
125: previous = next;
126: next = next->next;
127: PetscFree(previous->string);
128: PetscFree(previous);
129: }
130: vascii->petsc_printfqueue = 0;
131: vascii->petsc_printfqueuelength = 0;
132: for (i=1; i<size; i++) {
133: /* to prevent a flood of messages to process zero, request each message separately */
134: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
135: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
136: for (j=0; j<n; j++) {
137: PetscMPIInt size = 0;
139: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
140: PetscMalloc1(size, &message);
141: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
142: if (!vascii->bviewer) {
143: PetscFPrintf(comm,fd,"%s",message);
144: } else {
145: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
146: }
147: PetscFree(message);
148: }
149: }
150: } else { /* other processors send queue to processor 0 */
151: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
153: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
154: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
155: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
156: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
157: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
158: previous = next;
159: next = next->next;
160: PetscFree(previous->string);
161: PetscFree(previous);
162: }
163: vascii->petsc_printfqueue = 0;
164: vascii->petsc_printfqueuelength = 0;
165: }
166: PetscCommDestroy(&comm);
167: }
168: return(0);
169: }
171: /*@C
172: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
174: Not Collective
176: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
177: - fd - file pointer
179: Level: intermediate
181: Fortran Note:
182: This routine is not supported in Fortran.
184: Concepts: PetscViewer^file pointer
185: Concepts: file pointer^getting from PetscViewer
187: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
188: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
189: @*/
190: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
191: {
192: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
195: *fd = vascii->fd;
196: return(0);
197: }
199: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
200: {
201: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
204: *mode = vascii->mode;
205: return(0);
206: }
208: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
209: {
210: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
213: vascii->mode = mode;
214: return(0);
215: }
217: /*
218: If petsc_history is on, then all Petsc*Printf() results are saved
219: if the appropriate (usually .petschistory) file.
220: */
221: extern FILE *petsc_history;
223: /*@
224: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
226: Not Collective, but only first processor in set has any effect
228: Input Parameters:
229: + viewer - obtained with PetscViewerASCIIOpen()
230: - tabs - number of tabs
232: Level: developer
234: Fortran Note:
235: This routine is not supported in Fortran.
237: Concepts: PetscViewerASCII^formating
238: Concepts: tab^setting
240: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
241: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
242: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
243: @*/
244: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
245: {
246: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
247: PetscBool iascii;
248: PetscErrorCode ierr;
252: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253: if (iascii) ascii->tab = tabs;
254: return(0);
255: }
257: /*@
258: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
260: Not Collective, meaningful on first processor only.
262: Input Parameters:
263: . viewer - obtained with PetscViewerASCIIOpen()
264: Output Parameters:
265: . tabs - number of tabs
267: Level: developer
269: Fortran Note:
270: This routine is not supported in Fortran.
272: Concepts: PetscViewerASCII^formating
273: Concepts: tab^retrieval
275: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
276: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
277: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
278: @*/
279: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
280: {
281: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
282: PetscBool iascii;
283: PetscErrorCode ierr;
287: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
288: if (iascii && tabs) *tabs = ascii->tab;
289: return(0);
290: }
292: /*@
293: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
295: Not Collective, but only first processor in set has any effect
297: Input Parameters:
298: + viewer - obtained with PetscViewerASCIIOpen()
299: - tabs - number of tabs
301: Level: developer
303: Fortran Note:
304: This routine is not supported in Fortran.
306: Concepts: PetscViewerASCII^formating
307: Concepts: tab^setting
309: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
310: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
311: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
312: @*/
313: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
314: {
315: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
316: PetscBool iascii;
317: PetscErrorCode ierr;
321: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
322: if (iascii) ascii->tab += tabs;
323: return(0);
324: }
326: /*@
327: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
329: Not Collective, but only first processor in set has any effect
331: Input Parameters:
332: + viewer - obtained with PetscViewerASCIIOpen()
333: - tabs - number of tabs
335: Level: developer
337: Fortran Note:
338: This routine is not supported in Fortran.
340: Concepts: PetscViewerASCII^formating
341: Concepts: tab^setting
343: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
344: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
345: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
346: @*/
347: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
348: {
349: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
350: PetscBool iascii;
351: PetscErrorCode ierr;
355: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
356: if (iascii) ascii->tab -= tabs;
357: return(0);
358: }
360: /*@C
361: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
363: Collective on PetscViewer
365: Input Parameters:
366: . viewer - obtained with PetscViewerASCIIOpen()
368: Level: intermediate
370: Concepts: PetscViewerASCII^formating
371: Concepts: tab^setting
373: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
374: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
375: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
376: @*/
377: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
378: {
379: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
380: PetscBool iascii;
381: PetscErrorCode ierr;
385: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
386: if (iascii) ascii->allowsynchronized++;
387: return(0);
388: }
390: /*@C
391: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
393: Collective on PetscViewer
395: Input Parameters:
396: . viewer - obtained with PetscViewerASCIIOpen()
398: Level: intermediate
400: Concepts: PetscViewerASCII^formating
401: Concepts: tab^setting
403: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
404: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
405: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
406: @*/
407: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
408: {
409: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
410: PetscBool iascii;
411: PetscErrorCode ierr;
415: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
416: if (iascii) {
417: ascii->allowsynchronized--;
418: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
419: }
420: return(0);
421: }
423: /*@C
424: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
425: lines are tabbed.
427: Not Collective, but only first processor in set has any effect
429: Input Parameters:
430: . viewer - obtained with PetscViewerASCIIOpen()
432: Level: developer
434: Fortran Note:
435: This routine is not supported in Fortran.
437: Concepts: PetscViewerASCII^formating
438: Concepts: tab^setting
440: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
441: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
442: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
443: @*/
444: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
445: {
446: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
447: PetscBool iascii;
448: PetscErrorCode ierr;
452: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
453: if (iascii) ascii->tab++;
454: return(0);
455: }
457: /*@C
458: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
459: lines are tabbed.
461: Not Collective, but only first processor in set has any effect
463: Input Parameters:
464: . viewer - obtained with PetscViewerASCIIOpen()
466: Level: developer
468: Fortran Note:
469: This routine is not supported in Fortran.
471: Concepts: PetscViewerASCII^formating
472: Concepts: tab^setting
474: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
475: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
476: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
477: @*/
478: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
479: {
480: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
481: PetscErrorCode ierr;
482: PetscBool iascii;
486: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
487: if (iascii) {
488: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
489: ascii->tab--;
490: }
491: return(0);
492: }
494: /*@
495: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
497: Not Collective, but only first processor in set has any effect
499: Input Parameters:
500: + viewer - obtained with PetscViewerASCIIOpen()
501: - flg - PETSC_TRUE or PETSC_FALSE
503: Level: developer
505: Fortran Note:
506: This routine is not supported in Fortran.
508: Concepts: PetscViewerASCII^formating
509: Concepts: tab^setting
511: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
512: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
513: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
514: @*/
515: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
516: {
517: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
518: PetscBool iascii;
519: PetscErrorCode ierr;
523: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
524: if (iascii) {
525: if (flg) ascii->tab = ascii->tab_store;
526: else {
527: ascii->tab_store = ascii->tab;
528: ascii->tab = 0;
529: }
530: }
531: return(0);
532: }
534: /* ----------------------------------------------------------------------- */
537: /*@C
538: PetscViewerASCIIPrintf - Prints to a file, only from the first
539: processor in the PetscViewer
541: Not Collective, but only first processor in set has any effect
543: Input Parameters:
544: + viewer - obtained with PetscViewerASCIIOpen()
545: - format - the usual printf() format string
547: Level: developer
549: Fortran Note:
550: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
551: That is, you can only pass a single character string from Fortran.
553: Concepts: PetscViewerASCII^printing
554: Concepts: printing^to file
555: Concepts: printf
557: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
558: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
559: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
560: @*/
561: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
562: {
563: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
564: PetscMPIInt rank;
565: PetscInt tab,intab = ascii->tab;
566: PetscErrorCode ierr;
567: FILE *fd = ascii->fd;
568: PetscBool iascii;
569: int err;
574: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
575: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
576: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
577: if (rank) return(0);
579: if (ascii->bviewer) { /* pass string up to parent viewer */
580: char *string;
581: va_list Argp;
582: size_t fullLength;
584: PetscCalloc1(QUEUESTRINGSIZE, &string);
585: va_start(Argp,format);
586: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
587: va_end(Argp);
588: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
589: PetscFree(string);
590: } else { /* write directly to file */
591: va_list Argp;
592: /* flush my own messages that I may have queued up */
593: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
594: PetscInt i;
595: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
596: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
597: previous = next;
598: next = next->next;
599: PetscFree(previous->string);
600: PetscFree(previous);
601: }
602: ascii->petsc_printfqueue = 0;
603: ascii->petsc_printfqueuelength = 0;
604: tab = intab;
605: while (tab--) {
606: PetscFPrintf(PETSC_COMM_SELF,fd," ");
607: }
609: va_start(Argp,format);
610: (*PetscVFPrintf)(fd,format,Argp);
611: err = fflush(fd);
612: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
613: if (petsc_history) {
614: va_start(Argp,format);
615: tab = intab;
616: while (tab--) {
617: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
618: }
619: (*PetscVFPrintf)(petsc_history,format,Argp);
620: err = fflush(petsc_history);
621: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
622: }
623: va_end(Argp);
624: }
625: return(0);
626: }
628: /*@C
629: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
631: Collective on PetscViewer
633: Input Parameters:
634: + viewer - the PetscViewer; either ASCII or binary
635: - name - the name of the file it should use
637: Level: advanced
639: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
640: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
642: @*/
643: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
644: {
650: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
651: return(0);
652: }
654: /*@C
655: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
657: Not Collective
659: Input Parameter:
660: . viewer - the PetscViewer; either ASCII or binary
662: Output Parameter:
663: . name - the name of the file it is using
665: Level: advanced
667: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
669: @*/
670: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
671: {
676: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
677: return(0);
678: }
680: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
681: {
682: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
685: *name = vascii->filename;
686: return(0);
687: }
689: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
690: {
691: PetscErrorCode ierr;
692: size_t len;
693: char fname[PETSC_MAX_PATH_LEN],*gz;
694: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
695: PetscBool isstderr,isstdout;
696: PetscMPIInt rank;
699: PetscViewerFileClose_ASCII(viewer);
700: if (!name) return(0);
701: PetscStrallocpy(name,&vascii->filename);
703: /* Is this file to be compressed */
704: vascii->storecompressed = PETSC_FALSE;
706: PetscStrstr(vascii->filename,".gz",&gz);
707: if (gz) {
708: PetscStrlen(gz,&len);
709: if (len == 3) {
710: if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
711: *gz = 0;
712: vascii->storecompressed = PETSC_TRUE;
713: }
714: }
715: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
716: if (!rank) {
717: PetscStrcmp(name,"stderr",&isstderr);
718: PetscStrcmp(name,"stdout",&isstdout);
719: /* empty filename means stdout */
720: if (name[0] == 0) isstdout = PETSC_TRUE;
721: if (isstderr) vascii->fd = PETSC_STDERR;
722: else if (isstdout) vascii->fd = PETSC_STDOUT;
723: else {
726: PetscFixFilename(name,fname);
727: switch (vascii->mode) {
728: case FILE_MODE_READ:
729: vascii->fd = fopen(fname,"r");
730: break;
731: case FILE_MODE_WRITE:
732: vascii->fd = fopen(fname,"w");
733: break;
734: case FILE_MODE_APPEND:
735: vascii->fd = fopen(fname,"a");
736: break;
737: case FILE_MODE_UPDATE:
738: vascii->fd = fopen(fname,"r+");
739: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
740: break;
741: case FILE_MODE_APPEND_UPDATE:
742: /* I really want a file which is opened at the end for updating,
743: not a+, which opens at the beginning, but makes writes at the end.
744: */
745: vascii->fd = fopen(fname,"r+");
746: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
747: else {
748: fseek(vascii->fd, 0, SEEK_END);
749: }
750: break;
751: default:
752: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
753: }
754: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
755: }
756: }
757: #if defined(PETSC_USE_LOG)
758: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
759: #endif
760: return(0);
761: }
763: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
764: {
765: PetscMPIInt rank;
766: PetscErrorCode ierr;
767: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
770: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
771: PetscViewerASCIIPushSynchronized(viewer);
772: PetscViewerCreate(subcomm,outviewer);
773: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
774: PetscViewerASCIIPushSynchronized(*outviewer);
775: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
776: ovascii->fd = vascii->fd;
777: ovascii->tab = vascii->tab;
778: ovascii->closefile = PETSC_FALSE;
780: vascii->sviewer = *outviewer;
782: (*outviewer)->format = viewer->format;
784: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
785: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
786: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
787: return(0);
788: }
790: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
791: {
792: PetscErrorCode ierr;
793: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
796: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
797: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
799: ascii->sviewer = 0;
800: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
801: PetscViewerDestroy(outviewer);
802: return(0);
803: }
805: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
806: {
807: PetscErrorCode ierr;
808: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
811: if (ascii->filename) {
812: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
813: }
814: return(0);
815: }
817: /*MC
818: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
821: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
822: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
823: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
825: Level: beginner
827: M*/
828: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
829: {
830: PetscViewer_ASCII *vascii;
831: PetscErrorCode ierr;
834: PetscNewLog(viewer,&vascii);
835: viewer->data = (void*)vascii;
837: viewer->ops->destroy = PetscViewerDestroy_ASCII;
838: viewer->ops->flush = PetscViewerFlush_ASCII;
839: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
840: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
841: viewer->ops->view = PetscViewerView_ASCII;
842: viewer->ops->read = PetscViewerASCIIRead;
844: /* defaults to stdout unless set with PetscViewerFileSetName() */
845: vascii->fd = PETSC_STDOUT;
846: vascii->mode = FILE_MODE_WRITE;
847: vascii->bviewer = 0;
848: vascii->subviewer = 0;
849: vascii->sviewer = 0;
850: vascii->tab = 0;
851: vascii->tab_store = 0;
852: vascii->filename = 0;
853: vascii->closefile = PETSC_TRUE;
855: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
856: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
857: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
858: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
859: return(0);
860: }
862: /*@C
863: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
864: several processors. Output of the first processor is followed by that of the
865: second, etc.
867: Not Collective, must call collective PetscViewerFlush() to get the results out
869: Input Parameters:
870: + viewer - the ASCII PetscViewer
871: - format - the usual printf() format string
873: Level: intermediate
875: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
877: Fortran Note:
878: Can only print a single character* string
880: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
881: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
882: PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
884: @*/
885: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
886: {
887: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
888: PetscErrorCode ierr;
889: PetscMPIInt rank;
890: PetscInt tab = vascii->tab;
891: MPI_Comm comm;
892: FILE *fp;
893: PetscBool iascii,hasbviewer = PETSC_FALSE;
894: int err;
899: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
900: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
901: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
903: PetscObjectGetComm((PetscObject)viewer,&comm);
904: MPI_Comm_rank(comm,&rank);
906: if (vascii->bviewer) {
907: hasbviewer = PETSC_TRUE;
908: if (!rank) {
909: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
910: PetscObjectGetComm((PetscObject)viewer,&comm);
911: MPI_Comm_rank(comm,&rank);
912: }
913: }
915: fp = vascii->fd;
917: if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
918: va_list Argp;
919: /* flush my own messages that I may have queued up */
920: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
921: PetscInt i;
922: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
923: PetscFPrintf(comm,fp,"%s",next->string);
924: previous = next;
925: next = next->next;
926: PetscFree(previous->string);
927: PetscFree(previous);
928: }
929: vascii->petsc_printfqueue = 0;
930: vascii->petsc_printfqueuelength = 0;
932: while (tab--) {
933: PetscFPrintf(PETSC_COMM_SELF,fp," ");
934: }
936: va_start(Argp,format);
937: (*PetscVFPrintf)(fp,format,Argp);
938: err = fflush(fp);
939: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
940: if (petsc_history) {
941: va_start(Argp,format);
942: (*PetscVFPrintf)(petsc_history,format,Argp);
943: err = fflush(petsc_history);
944: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
945: }
946: va_end(Argp);
947: } else { /* other processors add to queue */
948: char *string;
949: va_list Argp;
950: size_t fullLength;
951: PrintfQueue next;
953: PetscNew(&next);
954: if (vascii->petsc_printfqueue) {
955: vascii->petsc_printfqueue->next = next;
956: vascii->petsc_printfqueue = next;
957: } else {
958: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
959: }
960: vascii->petsc_printfqueuelength++;
961: next->size = QUEUESTRINGSIZE;
962: PetscMalloc1(next->size, &next->string);
963: PetscMemzero(next->string,next->size);
964: string = next->string;
965: tab *= 2;
966: while (tab--) {
967: *string++ = ' ';
968: }
969: va_start(Argp,format);
970: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
971: va_end(Argp);
972: }
973: return(0);
974: }
976: /*@C
977: PetscViewerASCIIRead - Reads from am ASCII file
979: Collective on MPI_Comm
981: Input Parameters:
982: + viewer - the ascii viewer
983: . data - location to write the data
984: . num - number of items of data to read
985: - datatype - type of data to read
987: Output Parameters:
988: . count - number of items of data actually read, or NULL
990: Level: beginner
992: Concepts: ascii files
994: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
995: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
996: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
997: @*/
998: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
999: {
1000: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1001: FILE *fd = vascii->fd;
1002: PetscInt i;
1003: int ret = 0;
1007: for (i=0; i<num; i++) {
1008: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1009: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1010: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1011: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1012: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1013: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1014: #if defined(PETSC_USE_REAL___FLOAT128)
1015: else if (dtype == PETSC___FLOAT128) {
1016: double tmp;
1017: ret = fscanf(fd, "%lg", &tmp);
1018: ((__float128*)data)[i] = tmp;
1019: }
1020: #endif
1021: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1022: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1023: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1024: }
1025: if (count) *count = i;
1026: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1027: return(0);
1028: }