Actual source code: filev.c

      1: #define PETSC_DLL

     3:  #include src/sys/src/viewer/viewerimpl.h
      4: #include "petscfix.h"
      5: #include <stdarg.h>

      7: typedef struct {
      8:   FILE          *fd;
      9:   PetscFileMode mode;           /* The mode in which to open the file */
     10:   PetscInt      tab;            /* how many times text is tabbed in from left */
     11:   PetscInt      tab_store;      /* store tabs value while tabs are turned off */
     12:   PetscViewer   bviewer;        /* if PetscViewer is a singleton, this points to mother */
     13:   PetscViewer   sviewer;        /* if PetscViewer has a singleton, this points to singleton */
     14:   char          *filename;
     15:   PetscTruth    storecompressed;
     16: } PetscViewer_ASCII;

     18: /* ----------------------------------------------------------------------*/
     21: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
     22: {
     23:   PetscMPIInt       rank;
     24:   PetscErrorCode    ierr;
     25:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

     28:   if (vascii->sviewer) {
     29:     SETERRQ(PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
     30:   }
     31:   MPI_Comm_rank(viewer->comm,&rank);
     32:   if (!rank && vascii->fd != stderr && vascii->fd != stdout) {
     33:     fclose(vascii->fd);
     34:     if (vascii->storecompressed) {
     35:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
     36:       FILE *fp;
     37:       PetscStrcpy(par,"gzip ");
     38:       PetscStrcat(par,vascii->filename);
     39: #if defined(PETSC_HAVE_POPEN)
     40:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
     41:       if (fgets(buf,1024,fp)) {
     42:         SETERRQ2(PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
     43:       }
     44:       PetscPClose(PETSC_COMM_SELF,fp);
     45: #else
     46:       SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
     47: #endif
     48:     }
     49:   }
     50:   PetscStrfree(vascii->filename);
     51:   PetscFree(vascii);
     52:   return(0);
     53: }

     57: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
     58: {
     59:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
     60:   PetscErrorCode    ierr;
     62:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
     63:   return(0);
     64: }

     68: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
     69: {
     70:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

     73:   fflush(vascii->fd);
     74:   return(0);
     75: }

     79: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
     80: {
     81:   PetscMPIInt       rank;
     82:   PetscErrorCode    ierr;
     83:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

     86:   MPI_Comm_rank(viewer->comm,&rank);
     87:   if (!rank) {
     88:     fflush(vascii->fd);
     89:   }

     91:   /*
     92:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
     93:   */
     94:   PetscSynchronizedFlush(viewer->comm);
     95:   return(0);
     96: }

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

    103:     Not Collective

    105: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
    106: -   fd - file pointer

    108:     Level: intermediate

    110:     Fortran Note:
    111:     This routine is not supported in Fortran.

    113:   Concepts: PetscViewer^file pointer
    114:   Concepts: file pointer^getting from PetscViewer

    116: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    117:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    118: @*/
    119: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    120: {
    121:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

    124:   *fd = vascii->fd;
    125:   return(0);
    126: }

    130: /*@C
    131:     PetscViewerASCIISetMode - Sets the mode in which to open the file.

    133:     Not Collective

    135: +   viewer - viewer context, obtained from PetscViewerASCIIOpen()
    136: -   mode   - The file mode

    138:     Level: intermediate

    140:     Fortran Note:
    141:     This routine is not supported in Fortran.

    143: .keywords: Viewer, file, get, pointer

    145: .seealso: PetscViewerASCIIOpen()
    146: @*/
    147: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetMode(PetscViewer viewer, PetscFileMode mode)
    148: {
    149:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

    152:   vascii->mode = mode;
    153:   return(0);
    154: }

    156: /*
    157:    If petsc_history is on, then all Petsc*Printf() results are saved
    158:    if the appropriate (usually .petschistory) file.
    159: */

    164: /*@C
    165:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

    169:     Input Parameters:
    170: +    viewer - optained with PetscViewerASCIIOpen()
    171: -    tabs - number of tabs

    173:     Level: developer

    175:     Fortran Note:
    176:     This routine is not supported in Fortran.

    178:   Concepts: PetscViewerASCII^formating
    179:   Concepts: tab^setting

    181: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    182:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    183:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    184: @*/
    185: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
    186: {
    187:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    188:   PetscTruth        iascii;
    189:   PetscErrorCode    ierr;

    193:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    194:   if (iascii) {
    195:     ascii->tab = tabs;
    196:   }
    197:   return(0);
    198: }

    202: /*@C
    203:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    204:      lines are tabbed.

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

    208:     Input Parameters:
    209: .    viewer - optained with PetscViewerASCIIOpen()

    211:     Level: developer

    213:     Fortran Note:
    214:     This routine is not supported in Fortran.

    216:   Concepts: PetscViewerASCII^formating
    217:   Concepts: tab^setting

    219: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    220:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    221:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    222: @*/
    223: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPushTab(PetscViewer viewer)
    224: {
    225:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    226:   PetscTruth        iascii;
    227:   PetscErrorCode    ierr;

    231:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    232:   if (iascii) {
    233:     ascii->tab++;
    234:   }
    235:   return(0);
    236: }

    240: /*@C
    241:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    242:      lines are tabbed.

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

    246:     Input Parameters:
    247: .    viewer - optained with PetscViewerASCIIOpen()

    249:     Level: developer

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

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

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

    269:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    270:   if (iascii) {
    271:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    272:     ascii->tab--;
    273:   }
    274:   return(0);
    275: }

    279: /*@C
    280:     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer

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

    284:     Input Parameters:
    285: +    viewer - optained with PetscViewerASCIIOpen()
    286: -    flg - PETSC_YES or PETSC_NO

    288:     Level: developer

    290:     Fortran Note:
    291:     This routine is not supported in Fortran.

    293:   Concepts: PetscViewerASCII^formating
    294:   Concepts: tab^setting

    296: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    297:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
    298:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    299: @*/
    300: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
    301: {
    302:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    303:   PetscTruth        iascii;
    304:   PetscErrorCode    ierr;

    308:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    309:   if (iascii) {
    310:     if (flg) {
    311:       ascii->tab       = ascii->tab_store;
    312:     } else {
    313:       ascii->tab_store = ascii->tab;
    314:       ascii->tab       = 0;
    315:     }
    316:   }
    317:   return(0);
    318: }

    320: /* ----------------------------------------------------------------------- */

    322:  #include src/sys/src/fileio/mprint.h

    326: /*@C
    327:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    328:     processor in the PetscViewer

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

    332:     Input Parameters:
    333: +    viewer - optained with PetscViewerASCIIOpen()
    334: -    format - the usual printf() format string

    336:     Level: developer

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

    342:   Concepts: PetscViewerASCII^printing
    343:   Concepts: printing^to file
    344:   Concepts: printf

    346: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    347:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    348:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    349: @*/
    350: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    351: {
    352:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    353:   PetscMPIInt       rank;
    354:   PetscInt          tab;
    355:   PetscErrorCode    ierr;
    356:   FILE              *fd = ascii->fd;
    357:   PetscTruth        iascii;

    362:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    363:   if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

    365:   MPI_Comm_rank(viewer->comm,&rank);
    366:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
    367:   if (!rank) {
    368:     va_list Argp;
    369:     if (ascii->bviewer) {
    370:       queuefile = fd;
    371:     }

    373:     tab = ascii->tab;
    374:     while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}

    376:     va_start(Argp,format);
    377:     PetscVFPrintf(fd,format,Argp);
    378:     fflush(fd);
    379:     if (petsc_history) {
    380:       tab = ascii->tab;
    381:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
    382:       PetscVFPrintf(petsc_history,format,Argp);
    383:       fflush(petsc_history);
    384:     }
    385:     va_end(Argp);
    386:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
    387:     va_list     Argp;
    388:     char        *string;

    390:     PrintfQueue next;
    391:     PetscNew(struct _PrintfQueue,&next);
    392:     if (queue) {queue->next = next; queue = next;}
    393:     else       {queuebase   = queue = next;}
    394:     queuelength++;
    395:     string = next->string;
    396:     PetscMemzero(string,QUEUESTRINGSIZE);
    397:     tab = 2*ascii->tab;
    398:     while (tab--) {*string++ = ' ';}
    399:     va_start(Argp,format);
    400:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
    401:     va_end(Argp);
    402:   }
    403:   return(0);
    404: }

    408: /*@C
    409:      PetscViewerSetFilename - Sets the name of the file the PetscViewer uses.

    411:     Collective on PetscViewer

    413:   Input Parameters:
    414: +  viewer - the PetscViewer; either ASCII or binary
    415: -  name - the name of the file it should use

    417:     Level: advanced

    419: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    420:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    422: @*/
    423: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename(PetscViewer viewer,const char name[])
    424: {
    425:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

    430:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerSetFilename_C",(void (**)(void))&f);
    431:   if (f) {
    432:     (*f)(viewer,name);
    433:   }

    435:   return(0);
    436: }

    440: /*@C
    441:      PetscViewerGetFilename - Gets the name of the file the PetscViewer uses.

    443:     Not Collective

    445:   Input Parameter:
    446: .  viewer - the PetscViewer; either ASCII or binary

    448:   Output Parameter:
    449: .  name - the name of the file it is using

    451:     Level: advanced

    453: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerSetFilename()

    455: @*/
    456: PetscErrorCode PETSC_DLLEXPORT PetscViewerGetFilename(PetscViewer viewer,char **name)
    457: {
    458:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

    462:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerGetFilename_C",(void (**)(void))&f);
    463:   if (f) {
    464:     (*f)(viewer,name);
    465:   }
    466:   return(0);
    467: }

    472: PetscErrorCode PETSC_DLLEXPORT PetscViewerGetFilename_ASCII(PetscViewer viewer,char **name)
    473: {
    474:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    477:   *name = vascii->filename;
    478:   return(0);
    479: }

    485: PetscErrorCode PETSC_DLLEXPORT PetscViewerSetFilename_ASCII(PetscViewer viewer,const char name[])
    486: {
    487:   PetscErrorCode    ierr;
    488:   size_t            len;
    489:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    490:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    491:   PetscTruth        isstderr,isstdout;
    492:   PetscMPIInt       rank;

    495:   if (!name) return(0);

    497:   PetscStrallocpy(name,&vascii->filename);

    499:   /* Is this file to be compressed */
    500:   vascii->storecompressed = PETSC_FALSE;
    501:   PetscStrstr(vascii->filename,".gz",&gz);
    502:   if (gz) {
    503:     PetscStrlen(gz,&len);
    504:     if (len == 3) {
    505:       *gz = 0;
    506:       vascii->storecompressed = PETSC_TRUE;
    507:     }
    508:   }
    509:   MPI_Comm_rank(viewer->comm,&rank);
    510:   if (!rank) {
    511:     PetscStrcmp(name,"stderr",&isstderr);
    512:     PetscStrcmp(name,"stdout",&isstdout);
    513:     if (isstderr)      vascii->fd = stderr;
    514:     else if (isstdout) vascii->fd = stdout;
    515:     else {
    516:       PetscFixFilename(name,fname);
    517:       switch(vascii->mode) {
    518:       case FILE_MODE_READ:
    519:         vascii->fd = fopen(fname,"r");
    520:         break;
    521:       case FILE_MODE_WRITE:
    522:         vascii->fd = fopen(fname,"w");
    523:         break;
    524:       case FILE_MODE_APPEND:
    525:         vascii->fd = fopen(fname,"a");
    526:         break;
    527:       case FILE_MODE_UPDATE:
    528:         vascii->fd = fopen(fname,"r+");
    529:         if (!vascii->fd) {
    530:           vascii->fd = fopen(fname,"w+");
    531:         }
    532:         break;
    533:       case FILE_MODE_APPEND_UPDATE:
    534:         /* I really want a file which is opened at the end for updating,
    535:            not a+, which opens at the beginning, but makes writes at the end.
    536:         */
    537:         vascii->fd = fopen(fname,"r+");
    538:         if (!vascii->fd) {
    539:           vascii->fd = fopen(fname,"w+");
    540:         } else {
    541:           fseek(vascii->fd, 0, SEEK_END);
    542:         }
    543:         break;
    544:       default:
    545:         SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
    546:       }
    547:       if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    548:     }
    549:   }
    550:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    551:   return(0);
    552: }

    557: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
    558: {
    559:   PetscMPIInt       rank;
    560:   PetscErrorCode    ierr;
    561:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
    562:   const char        *name;

    565:   if (vascii->sviewer) {
    566:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
    567:   }
    568:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
    569:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
    570:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    571:   ovascii->fd  = vascii->fd;
    572:   ovascii->tab = vascii->tab;

    574:   vascii->sviewer = *outviewer;

    576:   (*outviewer)->format     = viewer->format;
    577:   (*outviewer)->iformat    = viewer->iformat;

    579:   PetscObjectGetName((PetscObject)viewer,&name);
    580:   PetscObjectSetName((PetscObject)(*outviewer),name);

    582:   MPI_Comm_rank(viewer->comm,&rank);
    583:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    584:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
    585:   if (rank) {
    586:     (*outviewer)->ops->flush = 0;
    587:   } else {
    588:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
    589:   }
    590:   return(0);
    591: }

    595: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
    596: {
    597:   PetscErrorCode    ierr;
    598:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
    599:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

    602:   if (!ascii->sviewer) {
    603:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
    604:   }
    605:   if (ascii->sviewer != *outviewer) {
    606:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
    607:   }

    609:   ascii->sviewer             = 0;
    610:   vascii->fd                 = stdout;
    611:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    612:   PetscViewerDestroy(*outviewer);
    613:   PetscViewerFlush(viewer);
    614:   return(0);
    615: }

    620: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_ASCII(PetscViewer viewer)
    621: {
    622:   PetscViewer_ASCII *vascii;
    623:   PetscErrorCode    ierr;

    626:   PetscNew(PetscViewer_ASCII,&vascii);
    627:   viewer->data = (void*)vascii;

    629:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    630:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    631:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
    632:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

    634:   /* defaults to stdout unless set with PetscViewerSetFilename() */
    635:   vascii->fd             = stdout;
    636:   vascii->mode           = FILE_MODE_WRITE;
    637:   vascii->bviewer        = 0;
    638:   vascii->sviewer        = 0;
    639:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
    640:   viewer->iformat        = 0;
    641:   vascii->tab            = 0;
    642:   vascii->tab_store      = 0;
    643:   vascii->filename       = 0;

    645:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerSetFilename_C","PetscViewerSetFilename_ASCII",
    646:                                      PetscViewerSetFilename_ASCII);
    647:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerGetFilename_C","PetscViewerGetFilename_ASCII",
    648:                                      PetscViewerGetFilename_ASCII);

    650:   return(0);
    651: }

    657: /*@C
    658:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    659:     several processors.  Output of the first processor is followed by that of the
    660:     second, etc.

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

    664:     Input Parameters:
    665: +   viewer - the ASCII PetscViewer
    666: -   format - the usual printf() format string

    668:     Level: intermediate

    670:     Fortran Note:
    671:       Can only print a single character* string

    673: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
    674:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
    675:           PetscViewerASCIIPrintf()

    677: @*/
    678: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    679: {
    680:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
    681:   PetscErrorCode    ierr;
    682:   PetscMPIInt       rank;
    683:   PetscInt          tab = vascii->tab;
    684:   MPI_Comm          comm;
    685:   FILE              *fp;
    686:   PetscTruth        iascii;

    691:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
    692:   if (!iascii) SETERRQ(PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

    694:   comm = viewer->comm;
    695:   fp   = vascii->fd;
    696:   MPI_Comm_rank(comm,&rank);
    697:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
    698:

    700:   /* First processor prints immediately to fp */
    701:   if (!rank) {
    702:     va_list Argp;

    704:     while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fp,"  ");}

    706:     va_start(Argp,format);
    707:     PetscVFPrintf(fp,format,Argp);
    708:     fflush(fp);
    709:     queuefile = fp;
    710:     if (petsc_history) {
    711:       PetscVFPrintf(petsc_history,format,Argp);
    712:       fflush(petsc_history);
    713:     }
    714:     va_end(Argp);
    715:   } else { /* other processors add to local queue */
    716:     char        *string;
    717:     va_list     Argp;
    718:     PrintfQueue next;

    720:     PetscNew(struct _PrintfQueue,&next);
    721:     if (queue) {queue->next = next; queue = next;}
    722:     else       {queuebase   = queue = next;}
    723:     queuelength++;
    724:     string = next->string;
    725:     PetscMemzero(string,QUEUESTRINGSIZE);
    726:     tab *= 2;
    727:     while (tab--) {*string++ = ' ';}
    728:     va_start(Argp,format);
    729:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
    730:     va_end(Argp);
    731:   }
    732:   return(0);
    733: }