Actual source code: filev.c
petsc-3.9.4 2018-09-11
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
191: + viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
192: - fd - file pointer
194: Level: intermediate
196: Fortran Note:
197: This routine is not supported in Fortran.
199: Concepts: PetscViewer^file pointer
200: Concepts: file pointer^getting from PetscViewer
202: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
203: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
204: @*/
205: PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
206: {
207: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
210: *fd = vascii->fd;
211: return(0);
212: }
214: PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
215: {
216: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
219: *mode = vascii->mode;
220: return(0);
221: }
223: PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
224: {
225: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
228: vascii->mode = mode;
229: return(0);
230: }
232: /*
233: If petsc_history is on, then all Petsc*Printf() results are saved
234: if the appropriate (usually .petschistory) file.
235: */
236: extern FILE *petsc_history;
238: /*@
239: PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
241: Not Collective, but only first processor in set has any effect
243: Input Parameters:
244: + viewer - obtained with PetscViewerASCIIOpen()
245: - tabs - number of tabs
247: Level: developer
249: Fortran Note:
250: This routine is not supported in Fortran.
252: Concepts: PetscViewerASCII^formating
253: Concepts: tab^setting
255: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
256: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
257: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
258: @*/
259: PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
260: {
261: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
262: PetscBool iascii;
263: PetscErrorCode ierr;
267: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
268: if (iascii) ascii->tab = tabs;
269: return(0);
270: }
272: /*@
273: PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
275: Not Collective, meaningful on first processor only.
277: Input Parameters:
278: . viewer - obtained with PetscViewerASCIIOpen()
279: Output Parameters:
280: . tabs - number of tabs
282: Level: developer
284: Fortran Note:
285: This routine is not supported in Fortran.
287: Concepts: PetscViewerASCII^formating
288: Concepts: tab^retrieval
290: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
291: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
292: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
293: @*/
294: PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
295: {
296: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
297: PetscBool iascii;
298: PetscErrorCode ierr;
302: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
303: if (iascii && tabs) *tabs = ascii->tab;
304: return(0);
305: }
307: /*@
308: PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
310: Not Collective, but only first processor in set has any effect
312: Input Parameters:
313: + viewer - obtained with PetscViewerASCIIOpen()
314: - tabs - number of tabs
316: Level: developer
318: Fortran Note:
319: This routine is not supported in Fortran.
321: Concepts: PetscViewerASCII^formating
322: Concepts: tab^setting
324: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
325: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
326: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
327: @*/
328: PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
329: {
330: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
331: PetscBool iascii;
332: PetscErrorCode ierr;
336: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
337: if (iascii) ascii->tab += tabs;
338: return(0);
339: }
341: /*@
342: PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
344: Not Collective, but only first processor in set has any effect
346: Input Parameters:
347: + viewer - obtained with PetscViewerASCIIOpen()
348: - tabs - number of tabs
350: Level: developer
352: Fortran Note:
353: This routine is not supported in Fortran.
355: Concepts: PetscViewerASCII^formating
356: Concepts: tab^setting
358: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
359: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
360: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
361: @*/
362: PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
363: {
364: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
365: PetscBool iascii;
366: PetscErrorCode ierr;
370: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
371: if (iascii) ascii->tab -= tabs;
372: return(0);
373: }
375: /*@C
376: PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
378: Collective on PetscViewer
380: Input Parameters:
381: . viewer - obtained with PetscViewerASCIIOpen()
383: Level: intermediate
385: Concepts: PetscViewerASCII^formating
386: Concepts: tab^setting
388: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
389: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
390: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
391: @*/
392: PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
393: {
394: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
395: PetscBool iascii;
396: PetscErrorCode ierr;
400: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
401: if (iascii) ascii->allowsynchronized++;
402: return(0);
403: }
405: /*@C
406: PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
408: Collective on PetscViewer
410: Input Parameters:
411: . viewer - obtained with PetscViewerASCIIOpen()
413: Level: intermediate
415: Concepts: PetscViewerASCII^formating
416: Concepts: tab^setting
418: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
419: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
420: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
421: @*/
422: PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
423: {
424: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
425: PetscBool iascii;
426: PetscErrorCode ierr;
430: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
431: if (iascii) {
432: ascii->allowsynchronized--;
433: if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
434: }
435: return(0);
436: }
438: /*@C
439: PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
440: lines are tabbed.
442: Not Collective, but only first processor in set has any effect
444: Input Parameters:
445: . viewer - obtained with PetscViewerASCIIOpen()
447: Level: developer
449: Fortran Note:
450: This routine is not supported in Fortran.
452: Concepts: PetscViewerASCII^formating
453: Concepts: tab^setting
455: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
456: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
457: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
458: @*/
459: PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
460: {
461: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
462: PetscBool iascii;
463: PetscErrorCode ierr;
467: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
468: if (iascii) ascii->tab++;
469: return(0);
470: }
472: /*@C
473: PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
474: lines are tabbed.
476: Not Collective, but only first processor in set has any effect
478: Input Parameters:
479: . viewer - obtained with PetscViewerASCIIOpen()
481: Level: developer
483: Fortran Note:
484: This routine is not supported in Fortran.
486: Concepts: PetscViewerASCII^formating
487: Concepts: tab^setting
489: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
490: PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
491: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
492: @*/
493: PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
494: {
495: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
496: PetscErrorCode ierr;
497: PetscBool iascii;
501: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
502: if (iascii) {
503: if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
504: ascii->tab--;
505: }
506: return(0);
507: }
509: /*@
510: PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
512: Not Collective, but only first processor in set has any effect
514: Input Parameters:
515: + viewer - obtained with PetscViewerASCIIOpen()
516: - flg - PETSC_TRUE or PETSC_FALSE
518: Level: developer
520: Fortran Note:
521: This routine is not supported in Fortran.
523: Concepts: PetscViewerASCII^formating
524: Concepts: tab^setting
526: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
527: PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
528: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
529: @*/
530: PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
531: {
532: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
533: PetscBool iascii;
534: PetscErrorCode ierr;
538: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
539: if (iascii) {
540: if (flg) ascii->tab = ascii->tab_store;
541: else {
542: ascii->tab_store = ascii->tab;
543: ascii->tab = 0;
544: }
545: }
546: return(0);
547: }
549: /* ----------------------------------------------------------------------- */
552: /*@C
553: PetscViewerASCIIPrintf - Prints to a file, only from the first
554: processor in the PetscViewer
556: Not Collective, but only first processor in set has any effect
558: Input Parameters:
559: + viewer - obtained with PetscViewerASCIIOpen()
560: - format - the usual printf() format string
562: Level: developer
564: Fortran Note:
565: The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
566: That is, you can only pass a single character string from Fortran.
568: Concepts: PetscViewerASCII^printing
569: Concepts: printing^to file
570: Concepts: printf
572: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
573: PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
574: PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
575: @*/
576: PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
577: {
578: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
579: PetscMPIInt rank;
580: PetscInt tab,intab = ascii->tab;
581: PetscErrorCode ierr;
582: FILE *fd = ascii->fd;
583: PetscBool iascii;
584: int err;
589: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
590: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
591: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
592: if (rank) return(0);
594: if (ascii->bviewer) { /* pass string up to parent viewer */
595: char *string;
596: va_list Argp;
597: size_t fullLength;
599: PetscCalloc1(QUEUESTRINGSIZE, &string);
600: va_start(Argp,format);
601: PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
602: va_end(Argp);
603: PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
604: PetscFree(string);
605: } else { /* write directly to file */
606: va_list Argp;
607: /* flush my own messages that I may have queued up */
608: PrintfQueue next = ascii->petsc_printfqueuebase,previous;
609: PetscInt i;
610: for (i=0; i<ascii->petsc_printfqueuelength; i++) {
611: PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
612: previous = next;
613: next = next->next;
614: PetscFree(previous->string);
615: PetscFree(previous);
616: }
617: ascii->petsc_printfqueue = 0;
618: ascii->petsc_printfqueuelength = 0;
619: tab = intab;
620: while (tab--) {
621: PetscFPrintf(PETSC_COMM_SELF,fd," ");
622: }
624: va_start(Argp,format);
625: (*PetscVFPrintf)(fd,format,Argp);
626: err = fflush(fd);
627: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
628: if (petsc_history) {
629: va_start(Argp,format);
630: tab = intab;
631: while (tab--) {
632: PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");
633: }
634: (*PetscVFPrintf)(petsc_history,format,Argp);
635: err = fflush(petsc_history);
636: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
637: }
638: va_end(Argp);
639: }
640: return(0);
641: }
643: /*@C
644: PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
646: Collective on PetscViewer
648: Input Parameters:
649: + viewer - the PetscViewer; either ASCII or binary
650: - name - the name of the file it should use
652: Level: advanced
654: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
655: PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
657: @*/
658: PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
659: {
661: char b[PETSC_MAX_PATH_LEN];
666: PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
667: PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
668: return(0);
669: }
671: /*@C
672: PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
674: Not Collective
676: Input Parameter:
677: . viewer - the PetscViewer; either ASCII or binary
679: Output Parameter:
680: . name - the name of the file it is using
682: Level: advanced
684: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
686: @*/
687: PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
688: {
694: PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
695: return(0);
696: }
698: PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
699: {
700: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
703: *name = vascii->filename;
704: return(0);
705: }
707: PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
708: {
709: PetscErrorCode ierr;
710: size_t len;
711: char fname[PETSC_MAX_PATH_LEN],*gz;
712: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
713: PetscBool isstderr,isstdout;
714: PetscMPIInt rank;
717: PetscViewerFileClose_ASCII(viewer);
718: if (!name) return(0);
719: PetscStrallocpy(name,&vascii->filename);
721: /* Is this file to be compressed */
722: vascii->storecompressed = PETSC_FALSE;
724: PetscStrstr(vascii->filename,".gz",&gz);
725: if (gz) {
726: PetscStrlen(gz,&len);
727: if (len == 3) {
728: 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");
729: *gz = 0;
730: vascii->storecompressed = PETSC_TRUE;
731: }
732: }
733: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
734: if (!rank) {
735: PetscStrcmp(name,"stderr",&isstderr);
736: PetscStrcmp(name,"stdout",&isstdout);
737: /* empty filename means stdout */
738: if (name[0] == 0) isstdout = PETSC_TRUE;
739: if (isstderr) vascii->fd = PETSC_STDERR;
740: else if (isstdout) vascii->fd = PETSC_STDOUT;
741: else {
744: PetscFixFilename(name,fname);
745: switch (vascii->mode) {
746: case FILE_MODE_READ:
747: vascii->fd = fopen(fname,"r");
748: break;
749: case FILE_MODE_WRITE:
750: vascii->fd = fopen(fname,"w");
751: break;
752: case FILE_MODE_APPEND:
753: vascii->fd = fopen(fname,"a");
754: break;
755: case FILE_MODE_UPDATE:
756: vascii->fd = fopen(fname,"r+");
757: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
758: break;
759: case FILE_MODE_APPEND_UPDATE:
760: /* I really want a file which is opened at the end for updating,
761: not a+, which opens at the beginning, but makes writes at the end.
762: */
763: vascii->fd = fopen(fname,"r+");
764: if (!vascii->fd) vascii->fd = fopen(fname,"w+");
765: else {
766: fseek(vascii->fd, 0, SEEK_END);
767: }
768: break;
769: default:
770: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
771: }
772: if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
773: }
774: }
775: #if defined(PETSC_USE_LOG)
776: PetscLogObjectState((PetscObject)viewer,"File: %s",name);
777: #endif
778: return(0);
779: }
781: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
782: {
783: PetscMPIInt rank;
784: PetscErrorCode ierr;
785: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
788: if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
789: PetscViewerASCIIPushSynchronized(viewer);
790: PetscViewerCreate(subcomm,outviewer);
791: PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
792: PetscViewerASCIIPushSynchronized(*outviewer);
793: ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
794: ovascii->fd = vascii->fd;
795: ovascii->tab = vascii->tab;
796: ovascii->closefile = PETSC_FALSE;
798: vascii->sviewer = *outviewer;
800: (*outviewer)->format = viewer->format;
802: MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
803: ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
804: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
805: return(0);
806: }
808: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
809: {
810: PetscErrorCode ierr;
811: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
814: if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
815: if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
817: ascii->sviewer = 0;
818: (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
819: PetscViewerDestroy(outviewer);
820: return(0);
821: }
823: PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
824: {
825: PetscErrorCode ierr;
826: PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
829: if (ascii->filename) {
830: PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
831: }
832: return(0);
833: }
835: /*MC
836: PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
839: .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
840: PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
841: PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
843: Level: beginner
845: M*/
846: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
847: {
848: PetscViewer_ASCII *vascii;
849: PetscErrorCode ierr;
852: PetscNewLog(viewer,&vascii);
853: viewer->data = (void*)vascii;
855: viewer->ops->destroy = PetscViewerDestroy_ASCII;
856: viewer->ops->flush = PetscViewerFlush_ASCII;
857: viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
858: viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
859: viewer->ops->view = PetscViewerView_ASCII;
860: viewer->ops->read = PetscViewerASCIIRead;
862: /* defaults to stdout unless set with PetscViewerFileSetName() */
863: vascii->fd = PETSC_STDOUT;
864: vascii->mode = FILE_MODE_WRITE;
865: vascii->bviewer = 0;
866: vascii->subviewer = 0;
867: vascii->sviewer = 0;
868: vascii->tab = 0;
869: vascii->tab_store = 0;
870: vascii->filename = 0;
871: vascii->closefile = PETSC_TRUE;
873: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
874: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
875: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
876: PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
877: return(0);
878: }
880: /*@C
881: PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
882: several processors. Output of the first processor is followed by that of the
883: second, etc.
885: Not Collective, must call collective PetscViewerFlush() to get the results out
887: Input Parameters:
888: + viewer - the ASCII PetscViewer
889: - format - the usual printf() format string
891: Level: intermediate
893: Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
895: Fortran Note:
896: Can only print a single character* string
898: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
899: PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
900: PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
902: @*/
903: PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
904: {
905: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
906: PetscErrorCode ierr;
907: PetscMPIInt rank;
908: PetscInt tab = vascii->tab;
909: MPI_Comm comm;
910: FILE *fp;
911: PetscBool iascii,hasbviewer = PETSC_FALSE;
912: int err;
917: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
918: if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
919: if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
921: PetscObjectGetComm((PetscObject)viewer,&comm);
922: MPI_Comm_rank(comm,&rank);
924: if (vascii->bviewer) {
925: hasbviewer = PETSC_TRUE;
926: if (!rank) {
927: vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
928: PetscObjectGetComm((PetscObject)viewer,&comm);
929: MPI_Comm_rank(comm,&rank);
930: }
931: }
933: fp = vascii->fd;
935: if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
936: va_list Argp;
937: /* flush my own messages that I may have queued up */
938: PrintfQueue next = vascii->petsc_printfqueuebase,previous;
939: PetscInt i;
940: for (i=0; i<vascii->petsc_printfqueuelength; i++) {
941: PetscFPrintf(comm,fp,"%s",next->string);
942: previous = next;
943: next = next->next;
944: PetscFree(previous->string);
945: PetscFree(previous);
946: }
947: vascii->petsc_printfqueue = 0;
948: vascii->petsc_printfqueuelength = 0;
950: while (tab--) {
951: PetscFPrintf(PETSC_COMM_SELF,fp," ");
952: }
954: va_start(Argp,format);
955: (*PetscVFPrintf)(fp,format,Argp);
956: err = fflush(fp);
957: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
958: if (petsc_history) {
959: va_start(Argp,format);
960: (*PetscVFPrintf)(petsc_history,format,Argp);
961: err = fflush(petsc_history);
962: if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
963: }
964: va_end(Argp);
965: } else { /* other processors add to queue */
966: char *string;
967: va_list Argp;
968: size_t fullLength;
969: PrintfQueue next;
971: PetscNew(&next);
972: if (vascii->petsc_printfqueue) {
973: vascii->petsc_printfqueue->next = next;
974: vascii->petsc_printfqueue = next;
975: } else {
976: vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
977: }
978: vascii->petsc_printfqueuelength++;
979: next->size = QUEUESTRINGSIZE;
980: PetscMalloc1(next->size, &next->string);
981: PetscMemzero(next->string,next->size);
982: string = next->string;
983: tab *= 2;
984: while (tab--) {
985: *string++ = ' ';
986: }
987: va_start(Argp,format);
988: PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
989: va_end(Argp);
990: }
991: return(0);
992: }
994: /*@C
995: PetscViewerASCIIRead - Reads from am ASCII file
997: Collective on MPI_Comm
999: Input Parameters:
1000: + viewer - the ascii viewer
1001: . data - location to write the data
1002: . num - number of items of data to read
1003: - datatype - type of data to read
1005: Output Parameters:
1006: . count - number of items of data actually read, or NULL
1008: Level: beginner
1010: Concepts: ascii files
1012: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1013: VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1014: PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1015: @*/
1016: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1017: {
1018: PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1019: FILE *fd = vascii->fd;
1020: PetscInt i;
1021: int ret = 0;
1025: for (i=0; i<num; i++) {
1026: if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1027: else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1028: else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1029: else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1030: else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1031: else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1032: #if defined(PETSC_USE_REAL___FLOAT128)
1033: else if (dtype == PETSC___FLOAT128) {
1034: double tmp;
1035: ret = fscanf(fd, "%lg", &tmp);
1036: ((__float128*)data)[i] = tmp;
1037: }
1038: #endif
1039: else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1040: if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1041: else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1042: }
1043: if (count) *count = i;
1044: else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1045: return(0);
1046: }