Actual source code: petscvu.c

petsc-3.3-p7 2013-05-11
  2: #include <petsc-private/viewerimpl.h>  /*I     "petscsys.h"   I*/
  3: #include <stdarg.h>

  5: #define QUEUESTRINGSIZE 1024

  7: typedef struct _PrintfQueue *PrintfQueue;
  8: struct _PrintfQueue {
  9:   char        string[QUEUESTRINGSIZE];
 10:   PrintfQueue next;
 11: };

 13: typedef struct {
 14:   FILE          *fd;
 15:   PetscFileMode mode;     /* The mode in which to open the file */
 16:   char          *filename;
 17:   PetscBool     vecSeen;  /* The flag indicating whether any vector has been viewed so far */
 18:   PrintfQueue   queue, queueBase;
 19:   int           queueLength;
 20: } PetscViewer_VU;

 24: static PetscErrorCode PetscViewerFileClose_VU(PetscViewer viewer)
 25: {
 26:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 30:   if (vu->vecSeen) {
 31:     PetscViewerVUPrintDeferred(viewer, "};\n\n");
 32:   }
 33:   PetscViewerVUFlushDeferred(viewer);
 34:   PetscFClose(((PetscObject)viewer)->comm, vu->fd);
 35:   vu->fd = PETSC_NULL;
 36:   PetscFree(vu->filename);
 37:   return(0);
 38: }

 42: PetscErrorCode PetscViewerDestroy_VU(PetscViewer viewer)
 43: {
 44:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 48:   PetscViewerFileClose_VU(viewer);
 49:   PetscFree(vu);
 50:   return(0);
 51: }

 55: PetscErrorCode PetscViewerFlush_VU(PetscViewer viewer)
 56: {
 57:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
 58:   PetscMPIInt    rank;
 59:   int            err;

 63:   MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
 64:   if (!rank) {
 65:     err = fflush(vu->fd);
 66:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
 67:   }
 68:   return(0);
 69: }

 71: EXTERN_C_BEGIN
 74: PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
 75: {
 76:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

 79:   *name = vu->filename;
 80:   return(0);
 81: }
 82: EXTERN_C_END

 84: EXTERN_C_BEGIN
 87: PetscErrorCode  PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
 88: {
 89:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
 90:   char           fname[PETSC_MAX_PATH_LEN];
 91:   int            rank;

 95:   if (!name) return(0);
 96:   PetscViewerFileClose_VU(viewer);
 97:   MPI_Comm_rank(((PetscObject)viewer)->comm, &rank);
 98:   if (rank != 0) return(0);
 99:   PetscStrallocpy(name, &vu->filename);
100:   PetscFixFilename(name, fname);
101:   switch(vu->mode) {
102:   case FILE_MODE_READ:
103:     vu->fd = fopen(fname, "r");
104:     break;
105:   case FILE_MODE_WRITE:
106:     vu->fd = fopen(fname, "w");
107:     break;
108:   case FILE_MODE_APPEND:
109:     vu->fd = fopen(fname, "a");
110:     break;
111:   case FILE_MODE_UPDATE:
112:     vu->fd = fopen(fname, "r+");
113:     if (!vu->fd) {
114:       vu->fd = fopen(fname, "w+");
115:     }
116:     break;
117:   case FILE_MODE_APPEND_UPDATE:
118:     /* I really want a file which is opened at the end for updating,
119:        not a+, which opens at the beginning, but makes writes at the end.
120:     */
121:     vu->fd = fopen(fname, "r+");
122:     if (!vu->fd) {
123:       vu->fd = fopen(fname, "w+");
124:     } else {
125:       fseek(vu->fd, 0, SEEK_END);
126:     }
127:     break;
128:   default:
129:     SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vu->mode);
130:   }

132:   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
133: #if defined(PETSC_USE_LOG)
134:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
135: #endif

137:   return(0);
138: }
139: EXTERN_C_END

141: EXTERN_C_BEGIN
144: PetscErrorCode  PetscViewerCreate_VU(PetscViewer viewer)
145: {
146:   PetscViewer_VU *vu;

150:   PetscNewLog(viewer,PetscViewer_VU, &vu);
151:   viewer->data = (void*) vu;

153:   viewer->ops->destroy          = PetscViewerDestroy_VU;
154:   viewer->ops->flush            = PetscViewerFlush_VU;
155:   viewer->ops->getsingleton     = PETSC_NULL;
156:   viewer->ops->restoresingleton = PETSC_NULL;
157:   viewer->format                = PETSC_VIEWER_DEFAULT;
158:   viewer->iformat               = 0;

160:   vu->fd          = PETSC_NULL;
161:   vu->mode        = FILE_MODE_WRITE;
162:   vu->filename    = PETSC_NULL;
163:   vu->vecSeen     = PETSC_FALSE;
164:   vu->queue       = PETSC_NULL;
165:   vu->queueBase   = PETSC_NULL;
166:   vu->queueLength = 0;

168:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileSetName_C", "PetscViewerFileSetName_VU",
169:                                            PetscViewerFileSetName_VU);
170:   PetscObjectComposeFunctionDynamic((PetscObject) viewer,"PetscViewerFileGetName_C", "PetscViewerFileGetName_VU",
171:                                            PetscViewerFileGetName_VU);

173:   return(0);
174: }
175: EXTERN_C_END

179: /*@C
180:   PetscViewerVUGetPointer - Extracts the file pointer from a VU PetscViewer.

182:   Not Collective

184:   Input Parameter:
185: . viewer - The PetscViewer

187:   Output Parameter:
188: . fd     - The file pointer

190:   Level: intermediate

192:   Concepts: PetscViewer^file pointer
193:   Concepts: file pointer^getting from PetscViewer

195: .seealso: PetscViewerASCIIGetPointer()
196: @*/
197: PetscErrorCode  PetscViewerVUGetPointer(PetscViewer viewer, FILE **fd)
198: {
199:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

204:   *fd = vu->fd;
205:   return(0);
206: }

210: /*@C
211:   PetscViewerVUSetMode - Sets the mode in which to open the file.

213:   Not Collective

215:   Input Parameters:
216: + viewer - The PetscViewer
217: - mode   - The file mode

219:   Level: intermediate

221: .keywords: Viewer, file, get, pointer
222: .seealso: PetscViewerASCIISetMode()
223: @*/
224: PetscErrorCode  PetscViewerVUSetMode(PetscViewer viewer, PetscFileMode mode)
225: {
226:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

229:   vu->mode = mode;
230:   return(0);
231: }

235: /*@C
236:   PetscViewerVUSetVecSeen - Sets the flag which indicates whether we have viewed
237:   a vector. This is usually called internally rather than by a user.

239:   Not Collective

241:   Input Parameters:
242: + viewer  - The PetscViewer
243: - vecSeen - The flag which indicates whether we have viewed a vector

245:   Level: advanced

247: .keywords: Viewer, Vec
248: .seealso: PetscViewerVUGetVecSeen()
249: @*/
250: PetscErrorCode  PetscViewerVUSetVecSeen(PetscViewer viewer, PetscBool  vecSeen)
251: {
252:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

255:   vu->vecSeen = vecSeen;
256:   return(0);
257: }

261: /*@C
262:   PetscViewerVUGetVecSeen - Gets the flag which indicates whether we have viewed
263:   a vector. This is usually called internally rather than by a user.

265:   Not Collective

267:   Input Parameter:
268: . viewer  - The PetscViewer

270:   Output Parameter:
271: . vecSeen - The flag which indicates whether we have viewed a vector

273:   Level: advanced

275: .keywords: Viewer, Vec
276: .seealso: PetscViewerVUGetVecSeen()
277: @*/
278: PetscErrorCode  PetscViewerVUGetVecSeen(PetscViewer viewer, PetscBool  *vecSeen)
279: {
280:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;

285:   *vecSeen = vu->vecSeen;
286:   return(0);
287: }

291: /*@C
292:   PetscViewerVUPrintDeferred - Prints to the deferred write cache instead of the file.

294:   Not Collective

296:   Input Parameters:
297: + viewer - The PetscViewer
298: - format - The format string

300:   Level: intermediate

302: .keywords: Viewer, print, deferred
303: .seealso: PetscViewerVUFlushDeferred()
304: @*/
305: PetscErrorCode  PetscViewerVUPrintDeferred(PetscViewer viewer, const char format[], ...)
306: {
307:   PetscViewer_VU *vu = (PetscViewer_VU *) viewer->data;
308:   va_list        Argp;
309:   size_t         fullLength;
310:   PrintfQueue    next;

314:   PetscNew(struct _PrintfQueue, &next);
315:   if (vu->queue) {
316:     vu->queue->next = next;
317:     vu->queue       = next;
318:     vu->queue->next = PETSC_NULL;
319:   } else {
320:     vu->queueBase   = vu->queue = next;
321:   }
322:   vu->queueLength++;

324:   va_start(Argp, format);
325:   PetscMemzero(next->string,QUEUESTRINGSIZE);
326:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
327:   va_end(Argp);
328:   return(0);
329: }

333: /*@C
334:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

336:   Not Collective

338:   Input Parameter:
339: + viewer - The PetscViewer

341:   Level: intermediate

343: .keywords: Viewer, flush, deferred
344: .seealso: PetscViewerVUPrintDeferred()
345: @*/
346: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
347: {
348:   PetscViewer_VU *vu   = (PetscViewer_VU *) viewer->data;
349:   PrintfQueue    next = vu->queueBase;
350:   PrintfQueue    previous;
351:   int            i;

355:   for(i = 0; i < vu->queueLength; i++) {
356:     PetscFPrintf(((PetscObject)viewer)->comm, vu->fd, "%s", next->string);
357:     previous = next;
358:     next     = next->next;
359:     PetscFree(previous);
360:   }
361:   vu->queue       = PETSC_NULL;
362:   vu->queueLength = 0;
363:   return(0);
364: }