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

      2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I "petscviewer.h" I*/

      4: #define QUEUESTRINGSIZE 8192

      8: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
      9: {
     10:   PetscErrorCode    ierr;
     11:   PetscMPIInt       rank;
     12:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     13:   int               err;

     16:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
     17:   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
     18:     if (vascii->fd && vascii->closefile) {
     19:       err = fclose(vascii->fd);
     20:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
     21:     }
     22:     if (vascii->storecompressed) {
     23:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
     24:       FILE *fp;
     25:       PetscStrcpy(par,"gzip ");
     26:       PetscStrcat(par,vascii->filename);
     27: #if defined(PETSC_HAVE_POPEN)
     28:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
     29:       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
     30:       PetscPClose(PETSC_COMM_SELF,fp,NULL);
     31: #else
     32:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
     33: #endif
     34:     }
     35:   }
     36:   PetscFree(vascii->filename);
     37:   return(0);
     38: }

     40: /* ----------------------------------------------------------------------*/
     43: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
     44: {
     45:   PetscErrorCode    ierr;
     46:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     47:   PetscViewerLink   *vlink;
     48:   PetscBool         flg;

     51:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
     52:   PetscViewerFileClose_ASCII(viewer);
     53:   PetscFree(vascii);

     55:   /* remove the viewer from the list in the MPI Communicator */
     56:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
     57:     MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
     58:   }

     60:   MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
     61:   if (flg) {
     62:     if (vlink && vlink->viewer == viewer) {
     63:       if (vlink->next) {
     64:         MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
     65:       } else {
     66:         MPI_Attr_delete(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
     67:       }
     68:       PetscFree(vlink);
     69:     } else {
     70:       while (vlink && vlink->next) {
     71:         if (vlink->next->viewer == viewer) {
     72:           PetscViewerLink *nv = vlink->next;
     73:           vlink->next = vlink->next->next;
     74:           PetscFree(nv);
     75:         }
     76:         vlink = vlink->next;
     77:       }
     78:     }
     79:   }
     80:   return(0);
     81: }

     85: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
     86: {
     87:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     88:   PetscErrorCode    ierr;

     91:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
     92:   return(0);
     93: }

     97: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
     98: {
     99:   PetscErrorCode    ierr;
    100:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    101:   int               err;
    102:   MPI_Comm          comm;
    103:   PetscMPIInt       rank,size;
    104:   FILE              *fd = vascii->fd;

    107:   PetscObjectGetComm((PetscObject)viewer,&comm);
    108:   MPI_Comm_rank(comm,&rank);
    109:   MPI_Comm_size(comm,&size);

    111:   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
    112:     err = fflush(vascii->fd);
    113:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
    114:   }

    116:   if (vascii->allowsynchronized) {
    117:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
    118:     char          *message;
    119:     MPI_Status    status;

    121:     PetscCommDuplicate(comm,&comm,&tag);

    123:     /* First processor waits for messages from all other processors */
    124:     if (!rank) {
    125:       /* flush my own messages that I may have queued up */
    126:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    127:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    128:         if (!vascii->bviewer) {
    129:           PetscFPrintf(comm,fd,"%s",next->string);
    130:         } else {
    131:           PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
    132:         }
    133:         previous = next;
    134:         next     = next->next;
    135:         PetscFree(previous->string);
    136:         PetscFree(previous);
    137:       }
    138:       vascii->petsc_printfqueue       = 0;
    139:       vascii->petsc_printfqueuelength = 0;
    140:       for (i=1; i<size; i++) {
    141:         /* to prevent a flood of messages to process zero, request each message separately */
    142:         MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
    143:         MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
    144:         for (j=0; j<n; j++) {
    145:           PetscMPIInt size = 0;

    147:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
    148:           PetscMalloc1(size, &message);
    149:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
    150:           if (!vascii->bviewer) {
    151:             PetscFPrintf(comm,fd,"%s",message);
    152:           } else {
    153:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
    154:           }
    155:           PetscFree(message);
    156:         }
    157:       }
    158:     } else { /* other processors send queue to processor 0 */
    159:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

    161:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
    162:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
    163:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    164:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
    165:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
    166:         previous = next;
    167:         next     = next->next;
    168:         PetscFree(previous->string);
    169:         PetscFree(previous);
    170:       }
    171:       vascii->petsc_printfqueue       = 0;
    172:       vascii->petsc_printfqueuelength = 0;
    173:     }
    174:     PetscCommDestroy(&comm);
    175:   }
    176:   return(0);
    177: }

    181: /*@C
    182:     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.

    184:     Not Collective

    186: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
    187: -   fd - file pointer

    189:     Level: intermediate

    191:     Fortran Note:
    192:     This routine is not supported in Fortran.

    194:   Concepts: PetscViewer^file pointer
    195:   Concepts: file pointer^getting from PetscViewer

    197: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    198:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    199: @*/
    200: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    201: {
    202:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    205:   *fd = vascii->fd;
    206:   return(0);
    207: }

    211: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
    212: {
    213:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    216:   *mode = vascii->mode;
    217:   return(0);
    218: }

    222: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
    223: {
    224:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    227:   vascii->mode = mode;
    228:   return(0);
    229: }

    231: /*
    232:    If petsc_history is on, then all Petsc*Printf() results are saved
    233:    if the appropriate (usually .petschistory) file.
    234: */
    235: extern FILE *petsc_history;

    239: /*@
    240:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

    242:     Not Collective, but only first processor in set has any effect

    244:     Input Parameters:
    245: +    viewer - obtained with PetscViewerASCIIOpen()
    246: -    tabs - number of tabs

    248:     Level: developer

    250:     Fortran Note:
    251:     This routine is not supported in Fortran.

    253:   Concepts: PetscViewerASCII^formating
    254:   Concepts: tab^setting

    256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
    257:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    258:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    259: @*/
    260: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
    261: {
    262:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    263:   PetscBool         iascii;
    264:   PetscErrorCode    ierr;

    268:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    269:   if (iascii) ascii->tab = tabs;
    270:   return(0);
    271: }

    275: /*@
    276:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

    278:     Not Collective, meaningful on first processor only.

    280:     Input Parameters:
    281: .    viewer - obtained with PetscViewerASCIIOpen()
    282:     Output Parameters:
    283: .    tabs - number of tabs

    285:     Level: developer

    287:     Fortran Note:
    288:     This routine is not supported in Fortran.

    290:   Concepts: PetscViewerASCII^formating
    291:   Concepts: tab^retrieval

    293: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
    294:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    295:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    296: @*/
    297: PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
    298: {
    299:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    300:   PetscBool         iascii;
    301:   PetscErrorCode    ierr;

    305:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    306:   if (iascii && tabs) *tabs = ascii->tab;
    307:   return(0);
    308: }

    312: /*@
    313:     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing

    315:     Not Collective, but only first processor in set has any effect

    317:     Input Parameters:
    318: +    viewer - obtained with PetscViewerASCIIOpen()
    319: -    tabs - number of tabs

    321:     Level: developer

    323:     Fortran Note:
    324:     This routine is not supported in Fortran.

    326:   Concepts: PetscViewerASCII^formating
    327:   Concepts: tab^setting

    329: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    330:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    331:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    332: @*/
    333: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
    334: {
    335:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    336:   PetscBool         iascii;
    337:   PetscErrorCode    ierr;

    341:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    342:   if (iascii) ascii->tab += tabs;
    343:   return(0);
    344: }

    348: /*@
    349:     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing

    351:     Not Collective, but only first processor in set has any effect

    353:     Input Parameters:
    354: +    viewer - obtained with PetscViewerASCIIOpen()
    355: -    tabs - number of tabs

    357:     Level: developer

    359:     Fortran Note:
    360:     This routine is not supported in Fortran.

    362:   Concepts: PetscViewerASCII^formating
    363:   Concepts: tab^setting

    365: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    366:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    367:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    368: @*/
    369: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
    370: {
    371:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    372:   PetscBool         iascii;
    373:   PetscErrorCode    ierr;

    377:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    378:   if (iascii) ascii->tab -= tabs;
    379:   return(0);
    380: }

    384: /*@C
    385:     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

    387:     Collective on PetscViewer

    389:     Input Parameters:
    390: .    viewer - obtained with PetscViewerASCIIOpen()

    392:     Level: intermediate

    394:   Concepts: PetscViewerASCII^formating
    395:   Concepts: tab^setting

    397: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    398:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    399:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    400: @*/
    401: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
    402: {
    403:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    404:   PetscBool         iascii;
    405:   PetscErrorCode    ierr;

    409:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    410:   if (iascii) ascii->allowsynchronized++;
    411:   return(0);
    412: }

    416: /*@C
    417:     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer

    419:     Collective on PetscViewer

    421:     Input Parameters:
    422: .    viewer - obtained with PetscViewerASCIIOpen()

    424:     Level: intermediate

    426:   Concepts: PetscViewerASCII^formating
    427:   Concepts: tab^setting

    429: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    430:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    431:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    432: @*/
    433: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
    434: {
    435:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    436:   PetscBool         iascii;
    437:   PetscErrorCode    ierr;

    441:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    442:   if (iascii) {
    443:     ascii->allowsynchronized--;
    444:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
    445:   }
    446:   return(0);
    447: }

    451: /*@
    452:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    453:      lines are tabbed.

    455:     Not Collective, but only first processor in set has any effect

    457:     Input Parameters:
    458: .    viewer - obtained with PetscViewerASCIIOpen()

    460:     Level: developer

    462:     Fortran Note:
    463:     This routine is not supported in Fortran.

    465:   Concepts: PetscViewerASCII^formating
    466:   Concepts: tab^setting

    468: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    469:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    470:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    471: @*/
    472: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
    473: {
    474:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    475:   PetscBool         iascii;
    476:   PetscErrorCode    ierr;

    480:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    481:   if (iascii) ascii->tab++;
    482:   return(0);
    483: }

    487: /*@
    488:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    489:      lines are tabbed.

    491:     Not Collective, but only first processor in set has any effect

    493:     Input Parameters:
    494: .    viewer - obtained with PetscViewerASCIIOpen()

    496:     Level: developer

    498:     Fortran Note:
    499:     This routine is not supported in Fortran.

    501:   Concepts: PetscViewerASCII^formating
    502:   Concepts: tab^setting

    504: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    505:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    506:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    507: @*/
    508: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
    509: {
    510:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    511:   PetscErrorCode    ierr;
    512:   PetscBool         iascii;

    516:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    517:   if (iascii) {
    518:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    519:     ascii->tab--;
    520:   }
    521:   return(0);
    522: }

    526: /*@
    527:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

    529:     Not Collective, but only first processor in set has any effect

    531:     Input Parameters:
    532: +    viewer - obtained with PetscViewerASCIIOpen()
    533: -    flg - PETSC_TRUE or PETSC_FALSE

    535:     Level: developer

    537:     Fortran Note:
    538:     This routine is not supported in Fortran.

    540:   Concepts: PetscViewerASCII^formating
    541:   Concepts: tab^setting

    543: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    544:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
    545:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    546: @*/
    547: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
    548: {
    549:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    550:   PetscBool         iascii;
    551:   PetscErrorCode    ierr;

    555:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    556:   if (iascii) {
    557:     if (flg) ascii->tab = ascii->tab_store;
    558:     else {
    559:       ascii->tab_store = ascii->tab;
    560:       ascii->tab       = 0;
    561:     }
    562:   }
    563:   return(0);
    564: }

    566: /* ----------------------------------------------------------------------- */

    571: /*@C
    572:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    573:     processor in the PetscViewer

    575:     Not Collective, but only first processor in set has any effect

    577:     Input Parameters:
    578: +    viewer - obtained with PetscViewerASCIIOpen()
    579: -    format - the usual printf() format string

    581:     Level: developer

    583:     Fortran Note:
    584:     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
    585:     That is, you can only pass a single character string from Fortran.

    587:   Concepts: PetscViewerASCII^printing
    588:   Concepts: printing^to file
    589:   Concepts: printf

    591: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    592:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    593:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
    594: @*/
    595: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    596: {
    597:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    598:   PetscMPIInt       rank;
    599:   PetscInt          tab,intab = ascii->tab;
    600:   PetscErrorCode    ierr;
    601:   FILE              *fd = ascii->fd;
    602:   PetscBool         iascii;
    603:   int               err;

    608:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    609:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    610:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    611:   if (rank) return(0);

    613:   if (ascii->bviewer) { /* pass string up to parent viewer */
    614:     char        *string;
    615:     va_list     Argp;
    616:     size_t      fullLength;

    618:     PetscCalloc1(QUEUESTRINGSIZE, &string);
    619:     va_start(Argp,format);
    620:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
    621:     va_end(Argp);
    622:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
    623:     PetscFree(string);
    624:   } else { /* write directly to file */
    625:     va_list Argp;
    626:     /* flush my own messages that I may have queued up */
    627:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
    628:     PetscInt    i;
    629:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
    630:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
    631:       previous = next;
    632:       next     = next->next;
    633:       PetscFree(previous->string);
    634:       PetscFree(previous);
    635:     }
    636:     ascii->petsc_printfqueue       = 0;
    637:     ascii->petsc_printfqueuelength = 0;
    638:     tab = intab;
    639:     while (tab--) {
    640:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    641:     }

    643:     va_start(Argp,format);
    644:     (*PetscVFPrintf)(fd,format,Argp);
    645:     err  = fflush(fd);
    646:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    647:     if (petsc_history) {
    648:       va_start(Argp,format);
    649:       tab = intab;
    650:       while (tab--) {
    651:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
    652:       }
    653:       (*PetscVFPrintf)(petsc_history,format,Argp);
    654:       err  = fflush(petsc_history);
    655:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    656:     }
    657:     va_end(Argp);
    658:   }
    659:   return(0);
    660: }

    664: /*@C
    665:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

    667:     Collective on PetscViewer

    669:   Input Parameters:
    670: +  viewer - the PetscViewer; either ASCII or binary
    671: -  name - the name of the file it should use

    673:     Level: advanced

    675: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    676:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    678: @*/
    679: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
    680: {

    686:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
    687:   return(0);
    688: }

    692: /*@C
    693:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

    695:     Not Collective

    697:   Input Parameter:
    698: .  viewer - the PetscViewer; either ASCII or binary

    700:   Output Parameter:
    701: .  name - the name of the file it is using

    703:     Level: advanced

    705: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()

    707: @*/
    708: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
    709: {

    714:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
    715:   return(0);
    716: }

    720: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
    721: {
    722:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    725:   *name = vascii->filename;
    726:   return(0);
    727: }

    731: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
    732: {
    733:   PetscErrorCode    ierr;
    734:   size_t            len;
    735:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    736:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    737:   PetscBool         isstderr,isstdout;
    738:   PetscMPIInt       rank;

    741:   PetscViewerFileClose_ASCII(viewer);
    742:   if (!name) return(0);
    743:   PetscStrallocpy(name,&vascii->filename);

    745:   /* Is this file to be compressed */
    746:   vascii->storecompressed = PETSC_FALSE;

    748:   PetscStrstr(vascii->filename,".gz",&gz);
    749:   if (gz) {
    750:     PetscStrlen(gz,&len);
    751:     if (len == 3) {
    752:       *gz = 0;
    753:       vascii->storecompressed = PETSC_TRUE;
    754:     }
    755:   }
    756:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    757:   if (!rank) {
    758:     PetscStrcmp(name,"stderr",&isstderr);
    759:     PetscStrcmp(name,"stdout",&isstdout);
    760:     /* empty filename means stdout */
    761:     if (name[0] == 0)  isstdout = PETSC_TRUE;
    762:     if (isstderr)      vascii->fd = PETSC_STDERR;
    763:     else if (isstdout) vascii->fd = PETSC_STDOUT;
    764:     else {

    767:       PetscFixFilename(name,fname);
    768:       switch (vascii->mode) {
    769:       case FILE_MODE_READ:
    770:         vascii->fd = fopen(fname,"r");
    771:         break;
    772:       case FILE_MODE_WRITE:
    773:         vascii->fd = fopen(fname,"w");
    774:         break;
    775:       case FILE_MODE_APPEND:
    776:         vascii->fd = fopen(fname,"a");
    777:         break;
    778:       case FILE_MODE_UPDATE:
    779:         vascii->fd = fopen(fname,"r+");
    780:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    781:         break;
    782:       case FILE_MODE_APPEND_UPDATE:
    783:         /* I really want a file which is opened at the end for updating,
    784:            not a+, which opens at the beginning, but makes writes at the end.
    785:         */
    786:         vascii->fd = fopen(fname,"r+");
    787:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    788:         else {
    789:           fseek(vascii->fd, 0, SEEK_END);
    790:         }
    791:         break;
    792:       default:
    793:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
    794:       }
    795:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    796:     }
    797:   }
    798: #if defined(PETSC_USE_LOG)
    799:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    800: #endif
    801:   return(0);
    802: }

    806: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    807: {
    808:   PetscMPIInt       rank;
    809:   PetscErrorCode    ierr;
    810:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

    813:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
    814:   PetscViewerASCIIPushSynchronized(viewer);
    815:   PetscViewerCreate(subcomm,outviewer);
    816:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
    817:   PetscViewerASCIIPushSynchronized(*outviewer);
    818:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    819:   ovascii->fd  = vascii->fd;
    820:   ovascii->tab = vascii->tab;
    821:   ovascii->closefile = PETSC_FALSE;

    823:   vascii->sviewer = *outviewer;

    825:   (*outviewer)->format  = viewer->format;

    827:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    828:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    829:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
    830:   return(0);
    831: }

    835: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
    836: {
    837:   PetscErrorCode    ierr;
    838:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

    841:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
    842:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");

    844:   ascii->sviewer             = 0;
    845:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    846:   PetscViewerDestroy(outviewer);
    847:   return(0);
    848: }

    852: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
    853: {
    854:   PetscErrorCode    ierr;
    855:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

    858:   if (ascii->filename) {
    859:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
    860:   }
    861:   return(0);
    862: }

    866: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
    867: {
    868:   PetscViewer_ASCII *vascii;
    869:   PetscErrorCode    ierr;

    872:   PetscNewLog(viewer,&vascii);
    873:   viewer->data = (void*)vascii;

    875:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    876:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    877:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
    878:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
    879:   viewer->ops->view             = PetscViewerView_ASCII;
    880:   viewer->ops->read             = PetscViewerASCIIRead;

    882:   /* defaults to stdout unless set with PetscViewerFileSetName() */
    883:   vascii->fd        = PETSC_STDOUT;
    884:   vascii->mode      = FILE_MODE_WRITE;
    885:   vascii->bviewer   = 0;
    886:   vascii->subviewer = 0;
    887:   vascii->sviewer   = 0;
    888:   vascii->tab       = 0;
    889:   vascii->tab_store = 0;
    890:   vascii->filename  = 0;
    891:   vascii->closefile = PETSC_TRUE;

    893:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
    894:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
    895:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
    896:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
    897:   return(0);
    898: }

    902: /*@C
    903:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    904:     several processors.  Output of the first processor is followed by that of the
    905:     second, etc.

    907:     Not Collective, must call collective PetscViewerFlush() to get the results out

    909:     Input Parameters:
    910: +   viewer - the ASCII PetscViewer
    911: -   format - the usual printf() format string

    913:     Level: intermediate

    915:     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.

    917:     Fortran Note:
    918:       Can only print a single character* string

    920: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
    921:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
    922:           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()

    924: @*/
    925: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    926: {
    927:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    928:   PetscErrorCode    ierr;
    929:   PetscMPIInt       rank;
    930:   PetscInt          tab = vascii->tab;
    931:   MPI_Comm          comm;
    932:   FILE              *fp;
    933:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
    934:   int               err;

    939:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    940:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    941:   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");

    943:   PetscObjectGetComm((PetscObject)viewer,&comm);
    944:   MPI_Comm_rank(comm,&rank);

    946:   if (vascii->bviewer) {
    947:     hasbviewer = PETSC_TRUE;
    948:     if (!rank) {
    949:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
    950:       PetscObjectGetComm((PetscObject)viewer,&comm);
    951:       MPI_Comm_rank(comm,&rank);
    952:     }
    953:   }

    955:   fp   = vascii->fd;

    957:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
    958:     va_list Argp;
    959:     /* flush my own messages that I may have queued up */
    960:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    961:     PetscInt    i;
    962:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    963:       PetscFPrintf(comm,fp,"%s",next->string);
    964:       previous = next;
    965:       next     = next->next;
    966:       PetscFree(previous->string);
    967:       PetscFree(previous);
    968:     }
    969:     vascii->petsc_printfqueue       = 0;
    970:     vascii->petsc_printfqueuelength = 0;

    972:     while (tab--) {
    973:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
    974:     }

    976:     va_start(Argp,format);
    977:     (*PetscVFPrintf)(fp,format,Argp);
    978:     err  = fflush(fp);
    979:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    980:     if (petsc_history) {
    981:       va_start(Argp,format);
    982:       (*PetscVFPrintf)(petsc_history,format,Argp);
    983:       err  = fflush(petsc_history);
    984:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    985:     }
    986:     va_end(Argp);
    987:   } else { /* other processors add to queue */
    988:     char        *string;
    989:     va_list     Argp;
    990:     size_t      fullLength;
    991:     PrintfQueue next;

    993:     PetscNew(&next);
    994:     if (vascii->petsc_printfqueue) {
    995:       vascii->petsc_printfqueue->next = next;
    996:       vascii->petsc_printfqueue       = next;
    997:     } else {
    998:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
    999:     }
    1000:     vascii->petsc_printfqueuelength++;
    1001:     next->size = QUEUESTRINGSIZE;
    1002:     PetscMalloc1(next->size, &next->string);
    1003:     PetscMemzero(next->string,next->size);
    1004:     string     = next->string;
    1005:     tab       *= 2;
    1006:     while (tab--) {
    1007:       *string++ = ' ';
    1008:     }
    1009:     va_start(Argp,format);
    1010:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
    1011:     va_end(Argp);
    1012:   }
    1013:   return(0);
    1014: }

    1018: /*@C
    1019:    PetscViewerASCIIRead - Reads from am ASCII file

    1021:    Collective on MPI_Comm

    1023:    Input Parameters:
    1024: +  viewer - the ascii viewer
    1025: .  data - location to write the data
    1026: .  num - number of items of data to read
    1027: -  datatype - type of data to read

    1029:    Output Parameters:
    1030: .  count - number of items of data actually read, or NULL

    1032:    Level: beginner

    1034:    Concepts: ascii files

    1036: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
    1037:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    1038:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
    1039: @*/
    1040: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
    1041: {
    1042:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    1043:   FILE              *fd = vascii->fd;
    1044:   PetscInt           i;
    1045:   int                ret = 0;

    1049:   for (i=0; i<num; i++) {
    1050:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
    1051:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
    1052: #if PETSC_USE_64BIT_INDICES
    1053: #if (PETSC_SIZEOF_LONG_LONG == 8)
    1054:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%ld",  &(((PetscInt*)data)[i]));
    1055: #else
    1056:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%lld",  &(((PetscInt*)data)[i]));
    1057: #endif
    1058: #else
    1059:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%d",  &(((PetscInt*)data)[i]));
    1060: #endif
    1061:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
    1062:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
    1063:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
    1064:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
    1065:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
    1066:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
    1067:   }
    1068:   if (count) *count = i;
    1069:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
    1070:   return(0);
    1071: }