Actual source code: filev.c
petsc-3.11.1 2019-04-12
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: PetscStrncpy(par,"gzip ",sizeof(par));
24: PetscStrlcat(par,vascii->filename,sizeof(par));
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);
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_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
54: }
56: MPI_Comm_get_attr(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_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
61: } else {
62: MPI_Comm_delete_attr(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: }
77: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
78: PetscViewer aviewer;
79: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
80: if (flg && aviewer == viewer) {
81: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
82: }
83: }
84: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
85: PetscViewer aviewer;
86: MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
87: if (flg && aviewer == viewer) {
88: MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
89: }
90: }
91: return(0);
92: }
94: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
95: {
96: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
97: PetscErrorCode ierr;
100: PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
101: return(0);
102: }
104: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
105: {
106: PetscErrorCode ierr;
107: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
108: int err;
109: MPI_Comm comm;
110: PetscMPIInt rank,size;
111: FILE *fd = vascii->fd;
114: PetscObjectGetComm((PetscObject)viewer,&comm);
115: MPI_Comm_rank(comm,&rank);
116: MPI_Comm_size(comm,&size);
118: if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
119: err = fflush(vascii->fd);
120: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
121: }
123: if (vascii->allowsynchronized) {
124: PetscMPIInt tag,i,j,n = 0,dummy = 0;
125: char *message;
126: MPI_Status status;
128: PetscCommDuplicate(comm,&comm,&tag);
130: /* First processor waits for messages from all other processors */
131: if (!rank) {
132: /* flush my own messages that I may have queued up */
133: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
134: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
135: if (!vascii->bviewer) {
136: PetscFPrintf(comm,fd,"%s",next->string);
137: } else {
138: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
139: }
140: previous = next;
141: next = next->next;
142: PetscFree(previous->string);
143: PetscFree(previous);
144: }
145: vascii->petsc_printfqueue = 0;
146: vascii->petsc_printfqueuelength = 0;
147: for (i=1; i<size; i++) {
148: /* to prevent a flood of messages to process zero, request each message separately */
149: MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
150: MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
151: for (j=0; j<n; j++) {
152: PetscMPIInt size = 0;
154: MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
155: PetscMalloc1(size, &message);
156: MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
157: if (!vascii->bviewer) {
158: PetscFPrintf(comm,fd,"%s",message);
159: } else {
160: PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
161: }
162: PetscFree(message);
163: }
164: }
165: } else { /* other processors send queue to processor 0 */
166: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
168: MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
169: MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
170: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
171: MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
172: MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
173: previous = next;
174: next = next->next;
175: PetscFree(previous->string);
176: PetscFree(previous);
177: }
178: vascii->petsc_printfqueue = 0;
179: vascii->petsc_printfqueuelength = 0;
180: }
181: PetscCommDestroy(&comm);
182: }
183: return(0);
184: }
186: /*@C
187: PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
189: Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
191: Input Parameter:
192: . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
194: Output Parameter:
195: . fd - file pointer
197: Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
199: Level: intermediate
201: Fortran Note:
202: This routine is not supported in Fortran.
204: Concepts: PetscViewer^file pointer
205: Concepts: file pointer^getting from PetscViewer
207: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
208: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
209: @*/
210: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
211: {
212: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
215: *fd = vascii->fd;
216: return(0);
217: }
219: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
220: {
221: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
224: *mode = vascii->mode;
225: return(0);
226: }
228: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
229: {
230: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
233: vascii->mode = mode;
234: return(0);
235: }
237: /*
238: If petsc_history is on, then all Petsc*Printf() results are saved
239: if the appropriate (usually .petschistory) file.
240: */
241: PETSC_INTERN FILE *petsc_history;
243: /*@
244: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
246: Not Collective, but only first processor in set has any effect
248: Input Parameters:
249: + viewer - obtained with PetscViewerASCIIOpen()
250: - tabs - number of tabs
252: Level: developer
254: Fortran Note:
255: This routine is not supported in Fortran.
257: Concepts: PetscViewerASCII^formating
258: Concepts: tab^setting
260: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
261: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
262: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
263: @*/
264: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
265: {
266: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
267: PetscBool iascii;
268: PetscErrorCode ierr;
272: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
273: if (iascii) ascii->tab = tabs;
274: return(0);
275: }
277: /*@
278: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
280: Not Collective, meaningful on first processor only.
282: Input Parameters:
283: . viewer - obtained with PetscViewerASCIIOpen()
284: Output Parameters:
285: . tabs - number of tabs
287: Level: developer
289: Fortran Note:
290: This routine is not supported in Fortran.
292: Concepts: PetscViewerASCII^formating
293: Concepts: tab^retrieval
295: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
296: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
297: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
298: @*/
299: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
300: {
301: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
302: PetscBool iascii;
303: PetscErrorCode ierr;
307: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
308: if (iascii && tabs) *tabs = ascii->tab;
309: return(0);
310: }
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: }
346: /*@
347: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
349: Not Collective, but only first processor in set has any effect
351: Input Parameters:
352: + viewer - obtained with PetscViewerASCIIOpen()
353: - tabs - number of tabs
355: Level: developer
357: Fortran Note:
358: This routine is not supported in Fortran.
360: Concepts: PetscViewerASCII^formating
361: Concepts: tab^setting
363: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
364: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
365: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
366: @*/
367: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
368: {
369: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
370: PetscBool iascii;
371: PetscErrorCode ierr;
375: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
376: if (iascii) ascii->tab -= tabs;
377: return(0);
378: }
380: /*@C
381: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
383: Collective on PetscViewer
385: Input Parameters:
386: . viewer - obtained with PetscViewerASCIIOpen()
388: Level: intermediate
390: Concepts: PetscViewerASCII^formating
391: Concepts: tab^setting
393: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
394: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
395: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
396: @*/
397: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
398: {
399: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
400: PetscBool iascii;
401: PetscErrorCode ierr;
405: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
406: if (iascii) ascii->allowsynchronized++;
407: return(0);
408: }
410: /*@C
411: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
413: Collective on PetscViewer
415: Input Parameters:
416: . viewer - obtained with PetscViewerASCIIOpen()
418: Level: intermediate
420: Concepts: PetscViewerASCII^formating
421: Concepts: tab^setting
423: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
424: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
425: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
426: @*/
427: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
428: {
429: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
430: PetscBool iascii;
431: PetscErrorCode ierr;
435: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
436: if (iascii) {
437: ascii->allowsynchronized--;
438: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
439: }
440: return(0);
441: }
443: /*@C
444: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
445: lines are tabbed.
447: Not Collective, but only first processor in set has any effect
449: Input Parameters:
450: . viewer - obtained with PetscViewerASCIIOpen()
452: Level: developer
454: Fortran Note:
455: This routine is not supported in Fortran.
457: Concepts: PetscViewerASCII^formating
458: Concepts: tab^setting
460: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
461: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
462: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
463: @*/
464: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
465: {
466: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
467: PetscBool iascii;
468: PetscErrorCode ierr;
472: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
473: if (iascii) ascii->tab++;
474: return(0);
475: }
477: /*@C
478: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
479: lines are tabbed.
481: Not Collective, but only first processor in set has any effect
483: Input Parameters:
484: . viewer - obtained with PetscViewerASCIIOpen()
486: Level: developer
488: Fortran Note:
489: This routine is not supported in Fortran.
491: Concepts: PetscViewerASCII^formating
492: Concepts: tab^setting
494: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
495: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
496: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
497: @*/
498: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
499: {
500: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
501: PetscErrorCode ierr;
502: PetscBool iascii;
506: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
507: if (iascii) {
508: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
509: ascii->tab--;
510: }
511: return(0);
512: }
514: /*@
515: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
517: Not Collective, but only first processor in set has any effect
519: Input Parameters:
520: + viewer - obtained with PetscViewerASCIIOpen()
521: - flg - PETSC_TRUE or PETSC_FALSE
523: Level: developer
525: Fortran Note:
526: This routine is not supported in Fortran.
528: Concepts: PetscViewerASCII^formating
529: Concepts: tab^setting
531: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
532: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
533: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
534: @*/
535: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
536: {
537: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
538: PetscBool iascii;
539: PetscErrorCode ierr;
543: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
544: if (iascii) {
545: if (flg) ascii->tab = ascii->tab_store;
546: else {
547: ascii->tab_store = ascii->tab;
548: ascii->tab = 0;
549: }
550: }
551: return(0);
552: }
554: /* ----------------------------------------------------------------------- */
557: /*@C
558: PetscViewerASCIIPrintf - Prints to a file, only from the first
559: processor in the PetscViewer
561: Not Collective, but only first processor in set has any effect
563: Input Parameters:
564: + viewer - obtained with PetscViewerASCIIOpen()
565: - format - the usual printf() format string
567: Level: developer
569: Fortran Note:
570: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
571: That is, you can only pass a single character string from Fortran.
573: Concepts: PetscViewerASCII^printing
574: Concepts: printing^to file
575: Concepts: printf
577: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
578: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
579: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
580: @*/
581: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
582: {
583: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
584: PetscMPIInt rank;
585: PetscInt tab,intab = ascii->tab;
586: PetscErrorCode ierr;
587: FILE *fd = ascii->fd;
588: PetscBool iascii;
589: int err;
594: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
595: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
596: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
597: if (rank) return(0);
599: if (ascii->bviewer) { /* pass string up to parent viewer */
600: char *string;
601: va_list Argp;
602: size_t fullLength;
604: PetscCalloc1(QUEUESTRINGSIZE, &string);
605: va_start(Argp,format);
606: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
607: va_end(Argp);
608: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
609: PetscFree(string);
610: } else { /* write directly to file */
611: va_list Argp;
612: /* flush my own messages that I may have queued up */
613: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
614: PetscInt i;
615: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
616: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
617: previous = next;
618: next = next->next;
619: PetscFree(previous->string);
620: PetscFree(previous);
621: }
622: ascii->petsc_printfqueue = 0;
623: ascii->petsc_printfqueuelength = 0;
624: tab = intab;
625: while (tab--) {
626: PetscFPrintf(PETSC_COMM_SELF,fd," ");
627: }
629: va_start(Argp,format);
630: (*PetscVFPrintf)(fd,format,Argp);
631: err = fflush(fd);
632: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
633: if (petsc_history) {
634: va_start(Argp,format);
635: tab = intab;
636: while (tab--) {
637: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
638: }
639: (*PetscVFPrintf)(petsc_history,format,Argp);
640: err = fflush(petsc_history);
641: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
642: }
643: va_end(Argp);
644: }
645: return(0);
646: }
648: /*@C
649: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
651: Collective on PetscViewer
653: Input Parameters:
654: + viewer - the PetscViewer; either ASCII or binary
655: - name - the name of the file it should use
657: Level: advanced
659: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
660: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
662: @*/
663: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
664: {
666: char b[PETSC_MAX_PATH_LEN];
671: PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
672: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
673: return(0);
674: }
676: /*@C
677: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
679: Not Collective
681: Input Parameter:
682: . viewer - the PetscViewer; either ASCII or binary
684: Output Parameter:
685: . name - the name of the file it is using
687: Level: advanced
689: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
691: @*/
692: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
693: {
699: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
700: return(0);
701: }
703: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
704: {
705: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
708: *name = vascii->filename;
709: return(0);
710: }
712: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
713: {
714: PetscErrorCode ierr;
715: size_t len;
716: char fname[PETSC_MAX_PATH_LEN],*gz;
717: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
718: PetscBool isstderr,isstdout;
719: PetscMPIInt rank;
722: PetscViewerFileClose_ASCII(viewer);
723: if (!name) return(0);
724: PetscStrallocpy(name,&vascii->filename);
726: /* Is this file to be compressed */
727: vascii->storecompressed = PETSC_FALSE;
729: PetscStrstr(vascii->filename,".gz",&gz);
730: if (gz) {
731: PetscStrlen(gz,&len);
732: if (len == 3) {
733: 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");
734: *gz = 0;
735: vascii->storecompressed = PETSC_TRUE;
736: }
737: }
738: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
739: if (!rank) {
740: PetscStrcmp(name,"stderr",&isstderr);
741: PetscStrcmp(name,"stdout",&isstdout);
742: /* empty filename means stdout */
743: if (name[0] == 0) isstdout = PETSC_TRUE;
744: if (isstderr) vascii->fd = PETSC_STDERR;
745: else if (isstdout) vascii->fd = PETSC_STDOUT;
746: else {
749: PetscFixFilename(name,fname);
750: switch (vascii->mode) {
751: case FILE_MODE_READ:
752: vascii->fd = fopen(fname,"r");
753: break;
754: case FILE_MODE_WRITE:
755: vascii->fd = fopen(fname,"w");
756: break;
757: case FILE_MODE_APPEND:
758: vascii->fd = fopen(fname,"a");
759: break;
760: case FILE_MODE_UPDATE:
761: vascii->fd = fopen(fname,"r+");
762: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
763: break;
764: case FILE_MODE_APPEND_UPDATE:
765: /* I really want a file which is opened at the end for updating,
766: not a+, which opens at the beginning, but makes writes at the end.
767: */
768: vascii->fd = fopen(fname,"r+");
769: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
770: else {
771: fseek(vascii->fd, 0, SEEK_END);
772: }
773: break;
774: default:
775: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
776: }
777: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
778: }
779: }
780: #if defined(PETSC_USE_LOG)
781: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
782: #endif
783: return(0);
784: }
786: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
787: {
788: PetscMPIInt rank;
789: PetscErrorCode ierr;
790: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
793: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
794: PetscViewerASCIIPushSynchronized(viewer);
795: PetscViewerCreate(subcomm,outviewer);
796: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
797: PetscViewerASCIIPushSynchronized(*outviewer);
798: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
799: ovascii->fd = vascii->fd;
800: ovascii->tab = vascii->tab;
801: ovascii->closefile = PETSC_FALSE;
803: vascii->sviewer = *outviewer;
805: (*outviewer)->format = viewer->format;
807: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
808: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
809: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
810: return(0);
811: }
813: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
814: {
815: PetscErrorCode ierr;
816: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
819: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
820: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
822: ascii->sviewer = 0;
823: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
824: PetscViewerDestroy(outviewer);
825: return(0);
826: }
828: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
829: {
830: PetscErrorCode ierr;
831: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
834: if (ascii->filename) {
835: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
836: }
837: return(0);
838: }
840: /*MC
841: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
844: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
845: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
846: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
848: Level: beginner
850: M*/
851: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
852: {
853: PetscViewer_ASCII *vascii;
854: PetscErrorCode ierr;
857: PetscNewLog(viewer,&vascii);
858: viewer->data = (void*)vascii;
860: viewer->ops->destroy = PetscViewerDestroy_ASCII;
861: viewer->ops->flush = PetscViewerFlush_ASCII;
862: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
863: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
864: viewer->ops->view = PetscViewerView_ASCII;
865: viewer->ops->read = PetscViewerASCIIRead;
867: /* defaults to stdout unless set with PetscViewerFileSetName() */
868: vascii->fd = PETSC_STDOUT;
869: vascii->mode = FILE_MODE_WRITE;
870: vascii->bviewer = 0;
871: vascii->subviewer = 0;
872: vascii->sviewer = 0;
873: vascii->tab = 0;
874: vascii->tab_store = 0;
875: vascii->filename = 0;
876: vascii->closefile = PETSC_TRUE;
878: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
879: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
880: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
881: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
882: return(0);
883: }
885: /*@C
886: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
887: several processors. Output of the first processor is followed by that of the
888: second, etc.
890: Not Collective, must call collective PetscViewerFlush() to get the results out
892: Input Parameters:
893: + viewer - the ASCII PetscViewer
894: - format - the usual printf() format string
896: Level: intermediate
898: Notes:
899: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
901: Fortran Note:
902: Can only print a single character* string
904: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
905: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
906: PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
908: @*/
909: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
910: {
911: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
912: PetscErrorCode ierr;
913: PetscMPIInt rank;
914: PetscInt tab = vascii->tab;
915: MPI_Comm comm;
916: FILE *fp;
917: PetscBool iascii,hasbviewer = PETSC_FALSE;
918: int err;
923: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
924: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
925: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
927: PetscObjectGetComm((PetscObject)viewer,&comm);
928: MPI_Comm_rank(comm,&rank);
930: if (vascii->bviewer) {
931: hasbviewer = PETSC_TRUE;
932: if (!rank) {
933: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
934: PetscObjectGetComm((PetscObject)viewer,&comm);
935: MPI_Comm_rank(comm,&rank);
936: }
937: }
939: fp = vascii->fd;
941: if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
942: va_list Argp;
943: /* flush my own messages that I may have queued up */
944: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
945: PetscInt i;
946: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
947: PetscFPrintf(comm,fp,"%s",next->string);
948: previous = next;
949: next = next->next;
950: PetscFree(previous->string);
951: PetscFree(previous);
952: }
953: vascii->petsc_printfqueue = 0;
954: vascii->petsc_printfqueuelength = 0;
956: while (tab--) {
957: PetscFPrintf(PETSC_COMM_SELF,fp," ");
958: }
960: va_start(Argp,format);
961: (*PetscVFPrintf)(fp,format,Argp);
962: err = fflush(fp);
963: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
964: if (petsc_history) {
965: va_start(Argp,format);
966: (*PetscVFPrintf)(petsc_history,format,Argp);
967: err = fflush(petsc_history);
968: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
969: }
970: va_end(Argp);
971: } else { /* other processors add to queue */
972: char *string;
973: va_list Argp;
974: size_t fullLength;
975: PrintfQueue next;
977: PetscNew(&next);
978: if (vascii->petsc_printfqueue) {
979: vascii->petsc_printfqueue->next = next;
980: vascii->petsc_printfqueue = next;
981: } else {
982: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
983: }
984: vascii->petsc_printfqueuelength++;
985: next->size = QUEUESTRINGSIZE;
986: PetscMalloc1(next->size, &next->string);
987: PetscMemzero(next->string,next->size);
988: string = next->string;
989: tab *= 2;
990: while (tab--) {
991: *string++ = ' ';
992: }
993: va_start(Argp,format);
994: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
995: va_end(Argp);
996: if (fullLength > (size_t) (next->size-2*vascii->tab)) {
997: PetscFree(next->string);
998: next->size = fullLength + 2*vascii->tab;
999: PetscMalloc1(next->size, &next->string);
1000: PetscMemzero(next->string,next->size);
1001: string = next->string;
1002: tab = 2*vascii->tab;
1003: while (tab--) {
1004: *string++ = ' ';
1005: }
1006: va_start(Argp,format);
1007: PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1008: va_end(Argp);
1009: }
1010: }
1011: return(0);
1012: }
1014: /*@C
1015: PetscViewerASCIIRead - Reads from a ASCII file
1017: Only process 0 in the PetscViewer may call this
1019: Input Parameters:
1020: + viewer - the ascii viewer
1021: . data - location to write the data
1022: . num - number of items of data to read
1023: - datatype - type of data to read
1025: Output Parameters:
1026: . count - number of items of data actually read, or NULL
1028: Level: beginner
1030: Concepts: ascii files
1032: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1033: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1034: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1035: @*/
1036: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1037: {
1038: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1039: FILE *fd = vascii->fd;
1040: PetscInt i;
1041: int ret = 0;
1042: PetscMPIInt rank;
1043: PetscErrorCode ierr;
1047: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1048: if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
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_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i]));
1055: else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1056: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1057: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1058: #if defined(PETSC_USE_REAL___FLOAT128)
1059: else if (dtype == PETSC___FLOAT128) {
1060: double tmp;
1061: ret = fscanf(fd, "%lg", &tmp);
1062: ((__float128*)data)[i] = tmp;
1063: }
1064: #endif
1065: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1066: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1067: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1068: }
1069: if (count) *count = i;
1070: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1071: return(0);
1072: }