Date: 2013-07-02T14:38:03+00:00

Actual source code: filev.c
petsc-3.4.2 2013-07-02

      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:       MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
     64:       PetscFree(vlink);
     65:     } else {
     66:       while (vlink && vlink->next) {
     67:         if (vlink->next->viewer == viewer) {
     68:           PetscViewerLink *nv = vlink->next;
     69:           vlink->next = vlink->next->next;
     70:           PetscFree(nv);
     71:         }
     72:         vlink = vlink->next;
     73:       }
     74:     }
     75:   }
     76:   return(0);
     77: }

     81: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
     82: {
     83:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     84:   PetscErrorCode    ierr;

     87:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
     88:   return(0);
     89: }

     93: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
     94: {
     95:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     96:   PetscErrorCode    ierr;

     99:   PetscViewerRestoreSubcomm(vascii->bviewer,PetscObjectComm((PetscObject)viewer),&viewer);
    100:   return(0);
    101: }

    105: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
    106: {
    107:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    108:   int               err;

    111:   err = fflush(vascii->fd);
    112:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    113:   return(0);
    114: }

    118: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
    119: {
    120:   PetscMPIInt       rank;
    121:   PetscErrorCode    ierr;
    122:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    123:   int               err;

    126:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    127:   /* fflush() fails on OSX for read-only descriptors */
    128:   if (!rank && (vascii->mode != FILE_MODE_READ)) {
    129:     err = fflush(vascii->fd);
    130:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
    131:   }

    133:   if (vascii->allowsynchronized) {
    134:     /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf()  */
    135:     PetscSynchronizedFlush(PetscObjectComm((PetscObject)viewer));
    136:   }
    137:   return(0);
    138: }

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

    145:     Not Collective

    147: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
    148: -   fd - file pointer

    150:     Level: intermediate

    152:     Fortran Note:
    153:     This routine is not supported in Fortran.

    155:   Concepts: PetscViewer^file pointer
    156:   Concepts: file pointer^getting from PetscViewer

    158: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    159:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    160: @*/
    161: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    162: {
    163:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    166:   *fd = vascii->fd;
    167:   return(0);
    168: }

    172: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
    173: {
    174:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    177:   *mode = vascii->mode;
    178:   return(0);
    179: }

    183: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
    184: {
    185:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    188:   vascii->mode = mode;
    189:   return(0);
    190: }

    192: /*
    193:    If petsc_history is on, then all Petsc*Printf() results are saved
    194:    if the appropriate (usually .petschistory) file.
    195: */
    196: extern FILE *petsc_history;

    200: /*@
    201:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

    205:     Input Parameters:
    206: +    viewer - optained with PetscViewerASCIIOpen()
    207: -    tabs - number of tabs

    209:     Level: developer

    211:     Fortran Note:
    212:     This routine is not supported in Fortran.

    214:   Concepts: PetscViewerASCII^formating
    215:   Concepts: tab^setting

    217: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
    218:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    219:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    220: @*/
    221: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
    222: {
    223:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    224:   PetscBool         iascii;
    225:   PetscErrorCode    ierr;

    229:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    230:   if (iascii) ascii->tab = tabs;
    231:   return(0);
    232: }

    236: /*@
    237:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

    239:     Not Collective, meaningful on first processor only.

    241:     Input Parameters:
    242: .    viewer - optained with PetscViewerASCIIOpen()
    243:     Output Parameters:
    244: .    tabs - number of tabs

    246:     Level: developer

    248:     Fortran Note:
    249:     This routine is not supported in Fortran.

    251:   Concepts: PetscViewerASCII^formating
    252:   Concepts: tab^retrieval

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

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

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

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

    278:     Input Parameters:
    279: +    viewer - optained with PetscViewerASCIIOpen()
    280: -    tabs - number of tabs

    282:     Level: developer

    284:     Fortran Note:
    285:     This routine is not supported in Fortran.

    287:   Concepts: PetscViewerASCII^formating
    288:   Concepts: tab^setting

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

    302:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    303:   if (iascii) ascii->tab += tabs;
    304:   return(0);
    305: }

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

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

    314:     Input Parameters:
    315: +    viewer - optained with PetscViewerASCIIOpen()
    316: -    tabs - number of tabs

    318:     Level: developer

    320:     Fortran Note:
    321:     This routine is not supported in Fortran.

    323:   Concepts: PetscViewerASCII^formating
    324:   Concepts: tab^setting

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

    338:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    339:   if (iascii) ascii->tab -= tabs;
    340:   return(0);
    341: }

    345: /*@C
    346:     PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

    348:     Collective on PetscViewer

    350:     Input Parameters:
    351: +    viewer - optained with PetscViewerASCIIOpen()
    352: -    allow - PETSC_TRUE to allow the synchronized printing

    354:     Level: intermediate

    356:   Concepts: PetscViewerASCII^formating
    357:   Concepts: tab^setting

    359: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    360:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    361:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    362: @*/
    363: PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
    364: {
    365:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    366:   PetscBool         iascii;
    367:   PetscErrorCode    ierr;

    371:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    372:   if (iascii) ascii->allowsynchronized = allow;
    373:   return(0);
    374: }

    378: /*@
    379:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    380:      lines are tabbed.

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

    384:     Input Parameters:
    385: .    viewer - optained with PetscViewerASCIIOpen()

    387:     Level: developer

    389:     Fortran Note:
    390:     This routine is not supported in Fortran.

    392:   Concepts: PetscViewerASCII^formating
    393:   Concepts: tab^setting

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

    407:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    408:   if (iascii) ascii->tab++;
    409:   return(0);
    410: }

    414: /*@
    415:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    416:      lines are tabbed.

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

    420:     Input Parameters:
    421: .    viewer - optained with PetscViewerASCIIOpen()

    423:     Level: developer

    425:     Fortran Note:
    426:     This routine is not supported in Fortran.

    428:   Concepts: PetscViewerASCII^formating
    429:   Concepts: tab^setting

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

    443:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    444:   if (iascii) {
    445:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    446:     ascii->tab--;
    447:   }
    448:   return(0);
    449: }

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

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

    458:     Input Parameters:
    459: +    viewer - optained with PetscViewerASCIIOpen()
    460: -    flg - PETSC_TRUE or PETSC_FALSE

    462:     Level: developer

    464:     Fortran Note:
    465:     This routine is not supported in Fortran.

    467:   Concepts: PetscViewerASCII^formating
    468:   Concepts: tab^setting

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

    482:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    483:   if (iascii) {
    484:     if (flg) ascii->tab = ascii->tab_store;
    485:     else {
    486:       ascii->tab_store = ascii->tab;
    487:       ascii->tab       = 0;
    488:     }
    489:   }
    490:   return(0);
    491: }

    493: /* ----------------------------------------------------------------------- */

    495: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */

    499: /*@C
    500:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    501:     processor in the PetscViewer

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

    505:     Input Parameters:
    506: +    viewer - optained with PetscViewerASCIIOpen()
    507: -    format - the usual printf() format string

    509:     Level: developer

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

    515:   Concepts: PetscViewerASCII^printing
    516:   Concepts: printing^to file
    517:   Concepts: printf

    519: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    520:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    521:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
    522: @*/
    523: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    524: {
    525:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    526:   PetscMPIInt       rank;
    527:   PetscInt          tab;
    528:   PetscErrorCode    ierr;
    529:   FILE              *fd = ascii->fd;
    530:   PetscBool         iascii;
    531:   int               err;

    536:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    537:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

    539:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    540:   if (!rank) {
    541:     va_list Argp;
    542:     if (ascii->bviewer) petsc_printfqueuefile = fd;

    544:     tab = ascii->tab;
    545:     while (tab--) {
    546:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    547:     }

    549:     va_start(Argp,format);
    550:     (*PetscVFPrintf)(fd,format,Argp);
    551:     err  = fflush(fd);
    552:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    553:     if (petsc_history) {
    554:       va_start(Argp,format);
    555:       tab = ascii->tab;
    556:       while (tab--) {
    557:         PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    558:       }
    559:       (*PetscVFPrintf)(petsc_history,format,Argp);
    560:       err  = fflush(petsc_history);
    561:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    562:     }
    563:     va_end(Argp);
    564:   }
    565:   return(0);
    566: }

    570: /*@C
    571:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

    573:     Collective on PetscViewer

    575:   Input Parameters:
    576: +  viewer - the PetscViewer; either ASCII or binary
    577: -  name - the name of the file it should use

    579:     Level: advanced

    581: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    582:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    584: @*/
    585: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
    586: {

    592:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
    593:   return(0);
    594: }

    598: /*@C
    599:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

    601:     Not Collective

    603:   Input Parameter:
    604: .  viewer - the PetscViewer; either ASCII or binary

    606:   Output Parameter:
    607: .  name - the name of the file it is using

    609:     Level: advanced

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

    613: @*/
    614: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
    615: {

    620:   PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
    621:   return(0);
    622: }

    626: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
    627: {
    628:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    631:   *name = vascii->filename;
    632:   return(0);
    633: }

    637: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
    638: {
    639:   PetscErrorCode    ierr;
    640:   size_t            len;
    641:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    642:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    643:   PetscBool         isstderr,isstdout;
    644:   PetscMPIInt       rank;

    647:   PetscViewerFileClose_ASCII(viewer);
    648:   if (!name) return(0);
    649:   PetscStrallocpy(name,&vascii->filename);

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

    654:   PetscStrstr(vascii->filename,".gz",&gz);
    655:   if (gz) {
    656:     PetscStrlen(gz,&len);
    657:     if (len == 3) {
    658:       *gz = 0;
    659:       vascii->storecompressed = PETSC_TRUE;
    660:     }
    661:   }
    662:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    663:   if (!rank) {
    664:     PetscStrcmp(name,"stderr",&isstderr);
    665:     PetscStrcmp(name,"stdout",&isstdout);
    666:     /* empty filename means stdout */
    667:     if (name[0] == 0)  isstdout = PETSC_TRUE;
    668:     if (isstderr)      vascii->fd = PETSC_STDERR;
    669:     else if (isstdout) vascii->fd = PETSC_STDOUT;
    670:     else {

    673:       PetscFixFilename(name,fname);
    674:       switch (vascii->mode) {
    675:       case FILE_MODE_READ:
    676:         vascii->fd = fopen(fname,"r");
    677:         break;
    678:       case FILE_MODE_WRITE:
    679:         vascii->fd = fopen(fname,"w");
    680:         break;
    681:       case FILE_MODE_APPEND:
    682:         vascii->fd = fopen(fname,"a");
    683:         break;
    684:       case FILE_MODE_UPDATE:
    685:         vascii->fd = fopen(fname,"r+");
    686:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    687:         break;
    688:       case FILE_MODE_APPEND_UPDATE:
    689:         /* I really want a file which is opened at the end for updating,
    690:            not a+, which opens at the beginning, but makes writes at the end.
    691:         */
    692:         vascii->fd = fopen(fname,"r+");
    693:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    694:         else {
    695:           fseek(vascii->fd, 0, SEEK_END);
    696:         }
    697:         break;
    698:       default:
    699:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
    700:       }
    701:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    702:     }
    703:   }
    704: #if defined(PETSC_USE_LOG)
    705:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    706: #endif
    707:   return(0);
    708: }

    712: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
    713: {
    714:   PetscMPIInt       rank;
    715:   PetscErrorCode    ierr;
    716:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
    717:   const char        *name;

    720:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
    721:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
    722:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
    723:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    724:   ovascii->fd  = vascii->fd;
    725:   ovascii->tab = vascii->tab;

    727:   vascii->sviewer = *outviewer;

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

    731:   PetscObjectGetName((PetscObject)viewer,&name);
    732:   PetscObjectSetName((PetscObject)(*outviewer),name);

    734:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    735:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    736:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
    737:   if (rank) (*outviewer)->ops->flush = 0;
    738:   else      (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
    739:   return(0);
    740: }

    744: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
    745: {
    746:   PetscErrorCode    ierr;
    747:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
    748:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

    751:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
    752:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");

    754:   ascii->sviewer             = 0;
    755:   vascii->fd                 = PETSC_STDOUT;
    756:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    757:   PetscViewerDestroy(outviewer);
    758:   PetscViewerFlush(viewer);
    759:   return(0);
    760: }

    764: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    765: {
    766:   PetscErrorCode    ierr;
    767:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
    768:   const char        *name;

    771:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
    772:   /* Note that we need to open vascii->filename for the subcomm:
    773:      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
    774:      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
    775:      will return the current viewer, having increfed it.
    776:    */
    777:   PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
    778:   if (*outviewer == viewer) return(0);
    779:   ovascii = (PetscViewer_ASCII*)(*outviewer)->data;

    781:   ovascii->tab    = vascii->tab;
    782:   vascii->sviewer = *outviewer;

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

    786:   PetscObjectGetName((PetscObject)viewer,&name);
    787:   PetscObjectSetName((PetscObject)(*outviewer),name);

    789:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;

    791:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
    792:   return(0);
    793: }

    797: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    798: {
    799:   PetscErrorCode    ierr;
    800:   PetscViewer_ASCII *oascii = (PetscViewer_ASCII*)(*outviewer)->data;
    801:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

    804:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
    805:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");

    807:   ascii->sviewer             = 0;
    808:   oascii->fd                 = PETSC_STDOUT;
    809:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;

    811:   PetscViewerDestroy(outviewer);
    812:   PetscViewerFlush(viewer);
    813:   return(0);
    814: }

    818: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
    819: {
    820:   PetscErrorCode    ierr;
    821:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

    824:   if (ascii->filename) {
    825:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
    826:   }
    827:   return(0);
    828: }

    832: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
    833: {
    834:   PetscViewer_ASCII *vascii;
    835:   PetscErrorCode    ierr;

    838:   PetscNewLog(viewer,PetscViewer_ASCII,&vascii);
    839:   viewer->data = (void*)vascii;

    841:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    842:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    843:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
    844:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
    845:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
    846:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;
    847:   viewer->ops->view             = PetscViewerView_ASCII;

    849:   /* defaults to stdout unless set with PetscViewerFileSetName() */
    850:   vascii->fd        = PETSC_STDOUT;
    851:   vascii->mode      = FILE_MODE_WRITE;
    852:   vascii->bviewer   = 0;
    853:   vascii->sviewer   = 0;
    854:   vascii->tab       = 0;
    855:   vascii->tab_store = 0;
    856:   vascii->filename  = 0;
    857:   vascii->closefile = PETSC_TRUE;

    859:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
    860:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
    861:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
    862:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
    863:   return(0);
    864: }

    869: /*@C
    870:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    871:     several processors.  Output of the first processor is followed by that of the
    872:     second, etc.

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

    876:     Input Parameters:
    877: +   viewer - the ASCII PetscViewer
    878: -   format - the usual printf() format string

    880:     Level: intermediate

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

    884:     Fortran Note:
    885:       Can only print a single character* string

    887: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
    888:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
    889:           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()

    891: @*/
    892: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    893: {
    894:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    895:   PetscErrorCode    ierr;
    896:   PetscMPIInt       rank,size;
    897:   PetscInt          tab = vascii->tab;
    898:   MPI_Comm          comm;
    899:   FILE              *fp;
    900:   PetscBool         iascii;
    901:   int               err;

    906:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    907:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    908:   MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);
    909:   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
    910:   if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */

    912:   PetscObjectGetComm((PetscObject)viewer,&comm);
    913:   fp   = vascii->fd;
    914:   MPI_Comm_rank(comm,&rank);

    916:   /* First processor prints immediately to fp */
    917:   if (!rank) {
    918:     va_list Argp;

    920:     while (tab--) {
    921:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
    922:     }

    924:     va_start(Argp,format);
    925:     (*PetscVFPrintf)(fp,format,Argp);
    926:     err  = fflush(fp);
    927:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    928:     petsc_printfqueuefile = fp;
    929:     if (petsc_history) {
    930:       va_start(Argp,format);
    931:       (*PetscVFPrintf)(petsc_history,format,Argp);
    932:       err  = fflush(petsc_history);
    933:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    934:     }
    935:     va_end(Argp);
    936:   } else { /* other processors add to local queue */
    937:     char        *string;
    938:     va_list     Argp;
    939:     size_t      fullLength;
    940:     PrintfQueue next;

    942:     PetscNew(struct _PrintfQueue,&next);
    943:     if (petsc_printfqueue) {
    944:       petsc_printfqueue->next = next;
    945:       petsc_printfqueue       = next;
    946:     } else {
    947:       petsc_printfqueuebase = petsc_printfqueue = next;
    948:     }
    949:     petsc_printfqueuelength++;
    950:     next->size = QUEUESTRINGSIZE;
    951:     PetscMalloc(next->size*sizeof(char), &next->string);
    952:     PetscMemzero(next->string,next->size);
    953:     string     = next->string;
    954:     tab       *= 2;
    955:     while (tab--) {
    956:       *string++ = ' ';
    957:     }
    958:     va_start(Argp,format);
    959:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
    960:     va_end(Argp);
    961:   }
    962:   return(0);
    963: }