Actual source code: petscvu.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      2: #include <petsc/private/viewerimpl.h>  /*I     "petscsys.h"   I*/

      4: #define QUEUESTRINGSIZE 1024

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

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

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

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

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

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

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

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

     72: PetscErrorCode  PetscViewerFileGetName_VU(PetscViewer viewer, const char **name)
     73: {
     74:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;

     77:   *name = vu->filename;
     78:   return(0);
     79: }

     83: PetscErrorCode  PetscViewerFileSetName_VU(PetscViewer viewer, const char name[])
     84: {
     85:   PetscViewer_VU *vu = (PetscViewer_VU*) viewer->data;
     86:   char           fname[PETSC_MAX_PATH_LEN];
     87:   int            rank;

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

    125:   if (!vu->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN, "Cannot open PetscViewer file: %s", fname);
    126: #if defined(PETSC_USE_LOG)
    127:   PetscLogObjectState((PetscObject) viewer, "File: %s", name);
    128: #endif
    129:   return(0);
    130: }

    134: PETSC_EXTERN PetscErrorCode PetscViewerCreate_VU(PetscViewer viewer)
    135: {
    136:   PetscViewer_VU *vu;

    140:   PetscNewLog(viewer,&vu);
    141:   viewer->data = (void*) vu;

    143:   viewer->ops->destroy          = PetscViewerDestroy_VU;
    144:   viewer->ops->flush            = PetscViewerFlush_VU;
    145:   viewer->ops->getsubviewer     = NULL;
    146:   viewer->ops->restoresubviewer = NULL;

    148:   vu->fd          = NULL;
    149:   vu->mode        = FILE_MODE_WRITE;
    150:   vu->filename    = NULL;
    151:   vu->vecSeen     = PETSC_FALSE;
    152:   vu->queue       = NULL;
    153:   vu->queueBase   = NULL;
    154:   vu->queueLength = 0;

    156:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_VU);
    157:   PetscObjectComposeFunction((PetscObject) viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_VU);
    158:   return(0);
    159: }

    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, PetscBool 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, PetscBool  *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:   size_t         fullLength;
    294:   PrintfQueue    next;

    298:   PetscNew(&next);
    299:   if (vu->queue) {
    300:     vu->queue->next = next;
    301:     vu->queue       = next;
    302:     vu->queue->next = NULL;
    303:   } else {
    304:     vu->queueBase   = vu->queue = next;
    305:   }
    306:   vu->queueLength++;

    308:   va_start(Argp, format);
    309:   PetscMemzero(next->string,QUEUESTRINGSIZE);
    310:   PetscVSNPrintf(next->string, QUEUESTRINGSIZE,format,&fullLength, Argp);
    311:   va_end(Argp);
    312:   return(0);
    313: }

    317: /*@C
    318:   PetscViewerVUFlushDeferred - Flushes the deferred write cache to the file.

    320:   Not Collective

    322:   Input Parameter:
    323: + viewer - The PetscViewer

    325:   Level: intermediate

    327: .keywords: Viewer, flush, deferred
    328: .seealso: PetscViewerVUPrintDeferred()
    329: @*/
    330: PetscErrorCode  PetscViewerVUFlushDeferred(PetscViewer viewer)
    331: {
    332:   PetscViewer_VU *vu  = (PetscViewer_VU*) viewer->data;
    333:   PrintfQueue    next = vu->queueBase;
    334:   PrintfQueue    previous;
    335:   int            i;

    339:   for (i = 0; i < vu->queueLength; i++) {
    340:     PetscFPrintf(PetscObjectComm((PetscObject)viewer), vu->fd, "%s", next->string);
    341:     previous = next;
    342:     next     = next->next;
    343:     PetscFree(previous);
    344:   }
    345:   vu->queue       = NULL;
    346:   vu->queueLength = 0;
    347:   return(0);
    348: }