Actual source code: petscvu.c
1: #define PETSC_DLL
3: #include private/viewerimpl.h
4: #include <stdarg.h>
6: #define QUEUESTRINGSIZE 1024
8: typedef struct _PrintfQueue *PrintfQueue;
9: struct _PrintfQueue {
10: char string[QUEUESTRINGSIZE];
11: PrintfQueue next;
12: };
14: typedef struct {
15: FILE *fd;
16: PetscFileMode mode; /* The mode in which to open the file */
17: char *filename;
18: PetscTruth vecSeen; /* The flag indicating whether any vector has been viewed so far */
19: PrintfQueue queue, queueBase;
20: int queueLength;
21: } PetscViewer_VU;
25: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
26: {
27: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
31: if (vu->vecSeen) {
32: PetscViewerVUPrintDeferred(viewer, "};\n\n");
33: }
34: PetscViewerVUFlushDeferred(viewer);
35: PetscFClose(((PetscObject)viewer)->comm, vu->fd);
36: PetscStrfree(vu->filename);
37: PetscFree(vu);
38: return(0);
39: }
43: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
44: {
45: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
46: PetscMPIInt rank;
47: int err;
51: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
52: if (!rank) {
53: err = fflush(vu->fd);
54: if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
55: }
56: return(0);
57: }
62: PetscErrorCode PetscViewerFileGetName_VU(PetscViewer viewer, char **name)
63: {
64: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
67: *name = vu->filename;
68: return(0);
69: }
75: PetscErrorCode PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
76: {
77: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
78: char fname[PETSC_MAX_PATH_LEN];
79: int rank;
83: if (!name) return(0);
84: MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
85: if (rank != 0) return(0);
86: PetscStrallocpy(name, &vu->filename);
87: PetscFixFilename(name, fname);
88: switch(vu->mode) {
89: case FILE_MODE_READ:
90: vu->fd = fopen(fname, "r");
91: break;
92: case FILE_MODE_WRITE:
93: vu->fd = fopen(fname, "w");
94: break;
95: case FILE_MODE_APPEND:
96: vu->fd = fopen(fname, "a");
97: break;
98: case FILE_MODE_UPDATE:
99: vu->fd = fopen(fname, "r+");
100: if (!vu->fd) {
101: vu->fd = fopen(fname, "w+");
102: }
103: break;
104: case FILE_MODE_APPEND_UPDATE:
105: /* I really want a file which is opened at the end for updating,
106: not a+, which opens at the beginning, but makes writes at the end.
107: */
108: vu->fd = fopen(fname, "r+");
109: if (!vu->fd) {
110: vu->fd = fopen(fname, "w+");
111: } else {
112: fseek(vu->fd, 0, SEEK_END);
113: }
114: break;
115: default:
116: SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
117: }
119: if (!vu->fd) SETERRQ1(PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
120: #if defined(PETSC_USE_LOG)
121: PetscLogObjectState((PetscObject) viewer, "File: %s", name);
122: #endif
124: return(0);
125: }
131: PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
132: {
133: PetscViewer_VU *vu;
137: PetscNewLog(viewer,PetscViewer_VU, &vu);
138: viewer->data = (void*) vu;
140: viewer->ops->destroy = PetscViewerDestroy_VU;
141: viewer->ops->flush = PetscViewerFlush_VU;
142: viewer->ops->getsingleton = PETSC_NULL;
143: viewer->ops->restoresingleton = PETSC_NULL;
144: viewer->format = PETSC_VIEWER_DEFAULT;
145: viewer->iformat = 0;
147: vu->fd = PETSC_NULL;
148: vu->mode = FILE_MODE_WRITE;
149: vu->filename = PETSC_NULL;
150: vu->vecSeen = PETSC_FALSE;
151: vu->queue = PETSC_NULL;
152: vu->queueBase = PETSC_NULL;
153: vu->queueLength = 0;
155: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
156: PetscViewerFileSetName_VU);
157: PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
158: PetscViewerFileGetName_VU);
160: return(0);
161: }
166: /*@C
167: PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.
169: Not Collective
171: Input Parameter:
172: . viewer - The PetscViewer
174: Output Parameter:
175: . fd - The file pointer
177: Level: intermediate
179: Concepts: PetscViewer^file pointer
180: Concepts: file pointer^getting from PetscViewer
182: .seealso: PetscViewerASCIIGetPointer()
183: @*/
184: PetscErrorCode PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
185: {
186: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
191: *fd = vu->fd;
192: return(0);
193: }
197: /*@C
198: PetscViewerVUSetMode - Sets the mode in which to open the file.
200: Not Collective
202: Input Parameters:
203: + viewer - The PetscViewer
204: - mode - The file mode
206: Level: intermediate
208: .keywords: Viewer, file, get, pointer
209: .seealso: PetscViewerASCIISetMode()
210: @*/
211: PetscErrorCode PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
212: {
213: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
216: vu->mode = mode;
217: return(0);
218: }
222: /*@C
223: PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
224: a vector. This is usually called internally rather than by a user.
226: Not Collective
228: Input Parameters:
229: + viewer - The PetscViewer
230: - vecSeen - The flag which indicates whether we have viewed a vector
232: Level: advanced
234: .keywords: Viewer, Vec
235: .seealso: PetscViewerVUGetVecSeen()
236: @*/
237: PetscErrorCode PetscViewerVUSetVecSeen(PetscViewer viewer, PetscTruth vecSeen)
238: {
239: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
242: vu->vecSeen = vecSeen;
243: return(0);
244: }
248: /*@C
249: PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
250: a vector. This is usually called internally rather than by a user.
252: Not Collective
254: Input Parameter:
255: . viewer - The PetscViewer
257: Output Parameter:
258: . vecSeen - The flag which indicates whether we have viewed a vector
260: Level: advanced
262: .keywords: Viewer, Vec
263: .seealso: PetscViewerVUGetVecSeen()
264: @*/
265: PetscErrorCode PetscViewerVUGetVecSeen(PetscViewer viewer, PetscTruth *vecSeen)
266: {
267: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
272: *vecSeen = vu->vecSeen;
273: return(0);
274: }
278: /*@C
279: PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.
281: Not Collective
283: Input Parameters:
284: + viewer - The PetscViewer
285: - format - The format string
287: Level: intermediate
289: .keywords: Viewer, print, deferred
290: .seealso: PetscViewerVUFlushDeferred()
291: @*/
292: PetscErrorCode PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
293: {
294: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
295: va_list Argp;
296: int fullLength;
297: PrintfQueue next;
301: PetscNew(struct _PrintfQueue, &next);
302: if (vu->queue) {
303: vu->queue->next = next;
304: vu->queue = next;
305: vu->queue->next = PETSC_NULL;
306: } else {
307: vu->queueBase = vu->queue = next;
308: }
309: vu->queueLength++;
311: va_start(Argp, format);
312: PetscMemzero(next->string,QUEUESTRINGSIZE);
313: PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
314: va_end(Argp);
315: return(0);
316: }
320: /*@C
321: PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.
323: Not Collective
325: Input Parameter:
326: + viewer - The PetscViewer
328: Level: intermediate
330: .keywords: Viewer, flush, deferred
331: .seealso: PetscViewerVUPrintDeferred()
332: @*/
333: PetscErrorCode PetscViewerVUFlushDeferred(PetscViewer viewer)
334: {
335: PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
336: PrintfQueue next = vu->queueBase;
337: PrintfQueue previous;
338: int i;
342: for(i = 0; i < vu->queueLength; i++) {
343: PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
344: previous = next;
345: next = next->next;
346: PetscFree(previous);
347: }
348: vu->queue = PETSC_NULL;
349: vu->queueLength = 0;
350: return(0);
351: }