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(((PetscObject)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: PetscMPIInt rank;
48: int err;
52: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
53: if (!rank) {
54: err = fflush(vu->fd);
55: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
56: }
57: return(0);
58: }
63: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, char **name)
64: {
65: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
68: *name = vu->filename;
69: return(0);
70: }
76: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
77: {
78: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
79: char fname[PETSC_MAX_PATH_LEN];
80: int rank;
84: if (!name) return(0);
85: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
86: if (rank != 0) return(0);
87: PetscStrallocpy(name, &vu->filename);
88: PetscFixFilename(name, fname);
89: switch(vu->mode) {
90: case FILE_MODE_READ:
91: vu->fd = fopen(fname, "r");
92: break;
93: case FILE_MODE_WRITE:
94: vu->fd = fopen(fname, "w");
95: break;
96: case FILE_MODE_APPEND:
97: vu->fd = fopen(fname, "a");
98: break;
99: case FILE_MODE_UPDATE:
100: vu->fd = fopen(fname, "r+");
101: if (!vu->fd) {
102: vu->fd = fopen(fname, "w+");
103: }
104: break;
105: case FILE_MODE_APPEND_UPDATE:
106: /* I really want a file which is opened at the end for updating,
107: not a+, which opens at the beginning, but makes writes at the end.
108: */
109: vu->fd = fopen(fname, "r+");
110: if (!vu->fd) {
111: vu->fd = fopen(fname, "w+");
112: } else {
113: fseek(vu->fd, 0, SEEK_END);
114: }
115: break;
116: default:
117: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
118: }
120: if (!vu->fd) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
121: #if defined(PETSC_USE_LOG)
122: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
123: #endif
125: return(0);
126: }
132: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
133: {
134: PetscViewer_VU *vu;
138: PetscNewLog(viewer,PetscViewer_VU, &vu);
139: viewer->data = (void*) vu;
141: viewer->ops->destroy = PetscViewerDestroy_VU;
142: viewer->ops->flush = PetscViewerFlush_VU;
143: viewer->ops->getsingleton = PETSC_NULL;
144: viewer->ops->restoresingleton = PETSC_NULL;
145: viewer->format = PETSC_VIEWER_DEFAULT;
146: viewer->iformat = 0;
148: vu->fd = PETSC_NULL;
149: vu->mode = FILE_MODE_WRITE;
150: vu->filename = PETSC_NULL;
151: vu->vecSeen = PETSC_FALSE;
152: vu->queue = PETSC_NULL;
153: vu->queueBase = PETSC_NULL;
154: vu->queueLength = 0;
156: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
157: PetscViewerFileSetName_VU);
158: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
159: PetscViewerFileGetName_VU);
161: return(0);
162: }
167: /*@C
168: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
170: Not Collective
172: Input Parameter:
173: . viewer - The PetscViewer
175: Output Parameter:
176: . fd - The file pointer
178: Level: intermediate
180: Concepts: PetscViewer^file pointer
181: Concepts: file pointer^getting from PetscViewer
183: .seealso: PetscViewerASCIIGetPointer()
184: @*/
185: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
186: {
187: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
192: *fd = vu->fd;
193: return(0);
194: }
198: /*@C
199: PetscViewerVUSetMode - Sets the mode in which to open the file.
201: Not Collective
203: Input Parameters:
204: + viewer - The PetscViewer
205: - mode - The file mode
207: Level: intermediate
209: .keywords: Viewer, file, get, pointer
210: .seealso: PetscViewerASCIISetMode()
211: @*/
212: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
213: {
214: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
217: vu->mode = mode;
218: return(0);
219: }
223: /*@C
224: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
225: a vector. This is usually called internally rather than by a user.
227: Not Collective
229: Input Parameters:
230: + viewer - The PetscViewer
231: - vecSeen - The flag which indicates whether we have viewed a vector
233: Level: advanced
235: .keywords: Viewer, Vec
236: .seealso: PetscViewerVUGetVecSeen()
237: @*/
238: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
239: {
240: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
243: vu->vecSeen = vecSeen;
244: return(0);
245: }
249: /*@C
250: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
251: a vector. This is usually called internally rather than by a user.
253: Not Collective
255: Input Parameter:
256: . viewer - The PetscViewer
258: Output Parameter:
259: . vecSeen - The flag which indicates whether we have viewed a vector
261: Level: advanced
263: .keywords: Viewer, Vec
264: .seealso: PetscViewerVUGetVecSeen()
265: @*/
266: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
267: {
268: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
273: *vecSeen = vu->vecSeen;
274: return(0);
275: }
279: /*@C
280: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
282: Not Collective
284: Input Parameters:
285: + viewer - The PetscViewer
286: - format - The format string
288: Level: intermediate
290: .keywords: Viewer, print, deferred
291: .seealso: PetscViewerVUFlushDeferred()
292: @*/
293: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
294: {
295: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
296: va_list Argp;
297: int fullLength;
298: PrintfQueue next;
302: PetscNew(struct _PrintfQueue, &next);
303: if (vu->queue) {
304: vu->queue->next = next;
305: vu->queue = next;
306: vu->queue->next = PETSC_NULL;
307: } else {
308: vu->queueBase = vu->queue = next;
309: }
310: vu->queueLength++;
312: va_start(Argp, format);
313: PetscMemzero(next->string,QUEUESTRINGSIZE);
314: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
315: va_end(Argp);
316: return(0);
317: }
321: /*@C
322: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
324: Not Collective
326: Input Parameter:
327: + viewer - The PetscViewer
329: Level: intermediate
331: .keywords: Viewer, flush, deferred
332: .seealso: PetscViewerVUPrintDeferred()
333: @*/
334: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
335: {
336: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
337: PrintfQueue next = vu->queueBase;
338: PrintfQueue previous;
339: int i;
343: for(i = 0; i < vu->queueLength; i++) {
344: PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
345: previous = next;
346: next = next->next;
347: PetscFree(previous);
348: }
349: vu->queue = PETSC_NULL;
350: vu->queueLength = 0;
351: return(0);
352: }