Actual source code: petscvu.c
1: #define PETSC_DLL
3: #include src/sys/viewer/viewerimpl.h
4: #include <stdarg.h>
5: #include "petscfix.h"
7: #define QUEUESTRINGSIZE 1024
9: typedef struct _PrintfQueue *PrintfQueue;
10: struct _PrintfQueue {
11: char string[QUEUESTRINGSIZE];
12: PrintfQueue next;
13: };
15: typedef struct {
16: FILE *fd;
17: PetscFileMode mode; /* The mode in which to open the file */
18: char *filename;
19: PetscTruth vecSeen; /* The flag indicating whether any vector has been viewed so far */
20: PrintfQueue queue, queueBase;
21: int queueLength;
22: } PetscViewer_VU;
26: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
27: {
28: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
32: if (vu->vecSeen) {
33: PetscViewerVUPrintDeferred(viewer, "};\n\n");
34: }
35: PetscViewerVUFlushDeferred(viewer);
36: PetscFClose(viewer->comm, vu->fd);
37: PetscStrfree(vu->filename);
38: PetscFree(vu);
39: return(0);
40: }
44: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
45: {
46: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
47: int rank;
51: MPI_Comm_rank(viewer->comm, &rank);
52: if (!rank) fflush(vu->fd);
53: return(0);
54: }
59: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, char **name)
60: {
61: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
64: *name = vu->filename;
65: return(0);
66: }
72: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
73: {
74: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
75: char fname[PETSC_MAX_PATH_LEN];
76: int rank;
80: if (!name) return(0);
81: MPI_Comm_rank(viewer->comm, &rank);
82: if (rank != 0) return(0);
83: PetscStrallocpy(name, &vu->filename);
84: PetscFixFilename(name, fname);
85: switch(vu->mode) {
86: case FILE_MODE_READ:
87: vu->fd = fopen(fname, "r");
88: break;
89: case FILE_MODE_WRITE:
90: vu->fd = fopen(fname, "w");
91: break;
92: case FILE_MODE_APPEND:
93: vu->fd = fopen(fname, "a");
94: break;
95: case FILE_MODE_UPDATE:
96: vu->fd = fopen(fname, "r+");
97: if (!vu->fd) {
98: vu->fd = fopen(fname, "w+");
99: }
100: break;
101: case FILE_MODE_APPEND_UPDATE:
102: /* I really want a file which is opened at the end for updating,
103: not a+, which opens at the beginning, but makes writes at the end.
104: */
105: vu->fd = fopen(fname, "r+");
106: if (!vu->fd) {
107: vu->fd = fopen(fname, "w+");
108: } else {
109: fseek(vu->fd, 0, SEEK_END);
110: }
111: break;
112: default:
113: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
114: }
116: if (!vu->fd) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
117: #if defined(PETSC_USE_LOG)
118: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
119: #endif
121: return(0);
122: }
128: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
129: {
130: PetscViewer_VU *vu;
134: PetscNew(PetscViewer_VU, &vu);
135: viewer->data = (void*) vu;
137: viewer->ops->destroy = PetscViewerDestroy_VU;
138: viewer->ops->flush = PetscViewerFlush_VU;
139: viewer->ops->getsingleton = PETSC_NULL;
140: viewer->ops->restoresingleton = PETSC_NULL;
141: viewer->format = PETSC_VIEWER_ASCII_DEFAULT;
142: viewer->iformat = 0;
144: vu->fd = PETSC_NULL;
145: vu->mode = FILE_MODE_WRITE;
146: vu->filename = PETSC_NULL;
147: vu->vecSeen = PETSC_FALSE;
148: vu->queue = PETSC_NULL;
149: vu->queueBase = PETSC_NULL;
150: vu->queueLength = 0;
152: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
153: PetscViewerFileSetName_VU);
154: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
155: PetscViewerFileGetName_VU);
157: return(0);
158: }
163: /*@C
164: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
166: Not Collective
168: Input Parameter:
169: . viewer - The PetscViewer
171: Output Parameter:
172: . fd - The file pointer
174: Level: intermediate
176: Concepts: PetscViewer^file pointer
177: Concepts: file pointer^getting from PetscViewer
179: .seealso: PetscViewerASCIIGetPointer()
180: @*/
181: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
182: {
183: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
188: *fd = vu->fd;
189: return(0);
190: }
194: /*@C
195: PetscViewerVUSetMode - Sets the mode in which to open the file.
197: Not Collective
199: Input Parameters:
200: + viewer - The PetscViewer
201: - mode - The file mode
203: Level: intermediate
205: .keywords: Viewer, file, get, pointer
206: .seealso: PetscViewerASCIISetMode()
207: @*/
208: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
209: {
210: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
213: vu->mode = mode;
214: return(0);
215: }
219: /*@C
220: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
221: a vector. This is usually called internally rather than by a user.
223: Not Collective
225: Input Parameters:
226: + viewer - The PetscViewer
227: - vecSeen - The flag which indicates whether we have viewed a vector
229: Level: advanced
231: .keywords: Viewer, Vec
232: .seealso: PetscViewerVUGetVecSeen()
233: @*/
234: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
235: {
236: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
239: vu->vecSeen = vecSeen;
240: return(0);
241: }
245: /*@C
246: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
247: a vector. This is usually called internally rather than by a user.
249: Not Collective
251: Input Parameter:
252: . viewer - The PetscViewer
254: Output Parameter:
255: . vecSeen - The flag which indicates whether we have viewed a vector
257: Level: advanced
259: .keywords: Viewer, Vec
260: .seealso: PetscViewerVUGetVecSeen()
261: @*/
262: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
263: {
264: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
269: *vecSeen = vu->vecSeen;
270: return(0);
271: }
275: /*@C
276: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
278: Not Collective
280: Input Parameters:
281: + viewer - The PetscViewer
282: - format - The format string
284: Level: intermediate
286: .keywords: Viewer, print, deferred
287: .seealso: PetscViewerVUFlushDeferred()
288: @*/
289: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
290: {
291: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
292: va_list Argp;
293: PrintfQueue next;
297: PetscNew(struct _PrintfQueue, &next);
298: if (vu->queue) {
299: vu->queue->next = next;
300: vu->queue = next;
301: vu->queue->next = PETSC_NULL;
302: } else {
303: vu->queueBase = vu->queue = next;
304: }
305: vu->queueLength++;
307: va_start(Argp, format);
308: PetscMemzero(next->string,QUEUESTRINGSIZE);
309: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format, Argp);
310: va_end(Argp);
311: return(0);
312: }
316: /*@C
317: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
319: Not Collective
321: Input Parameter:
322: + viewer - The PetscViewer
324: Level: intermediate
326: .keywords: Viewer, flush, deferred
327: .seealso: PetscViewerVUPrintDeferred()
328: @*/
329: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
330: {
331: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
332: PrintfQueue next = vu->queueBase;
333: PrintfQueue previous;
334: int i;
338: for(i = 0; i < vu->queueLength; i++) {
339: PetscFPrintf(viewer->comm, vu->fd, "%s", next->string);
340: previous = next;
341: next = next->next;
342: PetscFree(previous);
343: }
344: vu->queue = PETSC_NULL;
345: vu->queueLength = 0;
346: return(0);
347: }