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: }