Actual source code: filev.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

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

      4: #define QUEUESTRINGSIZE 8192

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

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

     38: /* ----------------------------------------------------------------------*/
     39: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
     40: {
     41:   PetscErrorCode    ierr;
     42:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
     43:   PetscViewerLink   *vlink;
     44:   PetscBool         flg;

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

     51:   /* remove the viewer from the list in the MPI Communicator */
     52:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
     53:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
     54:   }

     56:   MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
     57:   if (flg) {
     58:     if (vlink && vlink->viewer == viewer) {
     59:       if (vlink->next) {
     60:         MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
     61:       } else {
     62:         MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
     63:       }
     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:   }

     77:   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
     78:     PetscViewer aviewer;
     79:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     80:     if (flg && aviewer == viewer) {
     81:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
     82:     }
     83:   }
     84:   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
     85:     PetscViewer aviewer;
     86:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
     87:     if (flg && aviewer == viewer) {
     88:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
     89:     }
     90:   }
     91:   return(0);
     92: }

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

    100:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
    101:   return(0);
    102: }

    104: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
    105: {
    106:   PetscErrorCode    ierr;
    107:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    108:   int               err;
    109:   MPI_Comm          comm;
    110:   PetscMPIInt       rank,size;
    111:   FILE              *fd = vascii->fd;

    114:   PetscObjectGetComm((PetscObject)viewer,&comm);
    115:   MPI_Comm_rank(comm,&rank);
    116:   MPI_Comm_size(comm,&size);

    118:   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
    119:     err = fflush(vascii->fd);
    120:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
    121:   }

    123:   if (vascii->allowsynchronized) {
    124:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
    125:     char          *message;
    126:     MPI_Status    status;

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

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

    154:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
    155:           PetscMalloc1(size, &message);
    156:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
    157:           if (!vascii->bviewer) {
    158:             PetscFPrintf(comm,fd,"%s",message);
    159:           } else {
    160:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
    161:           }
    162:           PetscFree(message);
    163:         }
    164:       }
    165:     } else { /* other processors send queue to processor 0 */
    166:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

    168:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
    169:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
    170:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    171:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
    172:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
    173:         previous = next;
    174:         next     = next->next;
    175:         PetscFree(previous->string);
    176:         PetscFree(previous);
    177:       }
    178:       vascii->petsc_printfqueue       = 0;
    179:       vascii->petsc_printfqueuelength = 0;
    180:     }
    181:     PetscCommDestroy(&comm);
    182:   }
    183:   return(0);
    184: }

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

    189:     Not Collective

    191: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
    192: -   fd - file pointer

    194:     Level: intermediate

    196:     Fortran Note:
    197:     This routine is not supported in Fortran.

    199:   Concepts: PetscViewer^file pointer
    200:   Concepts: file pointer^getting from PetscViewer

    202: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
    203:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
    204: @*/
    205: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
    206: {
    207:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    210:   *fd = vascii->fd;
    211:   return(0);
    212: }

    214: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
    215: {
    216:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    219:   *mode = vascii->mode;
    220:   return(0);
    221: }

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

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

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

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

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

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

    247:     Level: developer

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

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

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

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

    272: /*@
    273:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

    275:     Not Collective, meaningful on first processor only.

    277:     Input Parameters:
    278: .    viewer - obtained with PetscViewerASCIIOpen()
    279:     Output Parameters:
    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^retrieval

    290: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
    291:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    292:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
    293: @*/
    294: PetscErrorCode  PetscViewerASCIIGetTab(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 && tabs) *tabs = ascii->tab;
    304:   return(0);
    305: }

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

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

    312:     Input Parameters:
    313: +    viewer - obtained with PetscViewerASCIIOpen()
    314: -    tabs - number of tabs

    316:     Level: developer

    318:     Fortran Note:
    319:     This routine is not supported in Fortran.

    321:   Concepts: PetscViewerASCII^formating
    322:   Concepts: tab^setting

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

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

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

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

    346:     Input Parameters:
    347: +    viewer - obtained with PetscViewerASCIIOpen()
    348: -    tabs - number of tabs

    350:     Level: developer

    352:     Fortran Note:
    353:     This routine is not supported in Fortran.

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

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

    370:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    371:   if (iascii) ascii->tab -= tabs;
    372:   return(0);
    373: }

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

    378:     Collective on PetscViewer

    380:     Input Parameters:
    381: .    viewer - obtained with PetscViewerASCIIOpen()

    383:     Level: intermediate

    385:   Concepts: PetscViewerASCII^formating
    386:   Concepts: tab^setting

    388: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    389:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    390:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    391: @*/
    392: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
    393: {
    394:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    395:   PetscBool         iascii;
    396:   PetscErrorCode    ierr;

    400:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    401:   if (iascii) ascii->allowsynchronized++;
    402:   return(0);
    403: }

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

    408:     Collective on PetscViewer

    410:     Input Parameters:
    411: .    viewer - obtained with PetscViewerASCIIOpen()

    413:     Level: intermediate

    415:   Concepts: PetscViewerASCII^formating
    416:   Concepts: tab^setting

    418: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    419:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    420:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    421: @*/
    422: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
    423: {
    424:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    425:   PetscBool         iascii;
    426:   PetscErrorCode    ierr;

    430:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    431:   if (iascii) {
    432:     ascii->allowsynchronized--;
    433:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
    434:   }
    435:   return(0);
    436: }

    438: /*@C
    439:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
    440:      lines are tabbed.

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

    444:     Input Parameters:
    445: .    viewer - obtained with PetscViewerASCIIOpen()

    447:     Level: developer

    449:     Fortran Note:
    450:     This routine is not supported in Fortran.

    452:   Concepts: PetscViewerASCII^formating
    453:   Concepts: tab^setting

    455: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    456:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    457:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    458: @*/
    459: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
    460: {
    461:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    462:   PetscBool         iascii;
    463:   PetscErrorCode    ierr;

    467:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    468:   if (iascii) ascii->tab++;
    469:   return(0);
    470: }

    472: /*@C
    473:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
    474:      lines are tabbed.

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

    478:     Input Parameters:
    479: .    viewer - obtained with PetscViewerASCIIOpen()

    481:     Level: developer

    483:     Fortran Note:
    484:     This routine is not supported in Fortran.

    486:   Concepts: PetscViewerASCII^formating
    487:   Concepts: tab^setting

    489: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    490:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
    491:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    492: @*/
    493: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
    494: {
    495:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    496:   PetscErrorCode    ierr;
    497:   PetscBool         iascii;

    501:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    502:   if (iascii) {
    503:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
    504:     ascii->tab--;
    505:   }
    506:   return(0);
    507: }

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

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

    514:     Input Parameters:
    515: +    viewer - obtained with PetscViewerASCIIOpen()
    516: -    flg - PETSC_TRUE or PETSC_FALSE

    518:     Level: developer

    520:     Fortran Note:
    521:     This routine is not supported in Fortran.

    523:   Concepts: PetscViewerASCII^formating
    524:   Concepts: tab^setting

    526: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
    527:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
    528:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
    529: @*/
    530: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
    531: {
    532:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    533:   PetscBool         iascii;
    534:   PetscErrorCode    ierr;

    538:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    539:   if (iascii) {
    540:     if (flg) ascii->tab = ascii->tab_store;
    541:     else {
    542:       ascii->tab_store = ascii->tab;
    543:       ascii->tab       = 0;
    544:     }
    545:   }
    546:   return(0);
    547: }

    549: /* ----------------------------------------------------------------------- */

    552: /*@C
    553:     PetscViewerASCIIPrintf - Prints to a file, only from the first
    554:     processor in the PetscViewer

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

    558:     Input Parameters:
    559: +    viewer - obtained with PetscViewerASCIIOpen()
    560: -    format - the usual printf() format string

    562:     Level: developer

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

    568:   Concepts: PetscViewerASCII^printing
    569:   Concepts: printing^to file
    570:   Concepts: printf

    572: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
    573:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
    574:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
    575: @*/
    576: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
    577: {
    578:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
    579:   PetscMPIInt       rank;
    580:   PetscInt          tab,intab = ascii->tab;
    581:   PetscErrorCode    ierr;
    582:   FILE              *fd = ascii->fd;
    583:   PetscBool         iascii;
    584:   int               err;

    589:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
    590:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
    591:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    592:   if (rank) return(0);

    594:   if (ascii->bviewer) { /* pass string up to parent viewer */
    595:     char        *string;
    596:     va_list     Argp;
    597:     size_t      fullLength;

    599:     PetscCalloc1(QUEUESTRINGSIZE, &string);
    600:     va_start(Argp,format);
    601:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
    602:     va_end(Argp);
    603:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
    604:     PetscFree(string);
    605:   } else { /* write directly to file */
    606:     va_list Argp;
    607:     /* flush my own messages that I may have queued up */
    608:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
    609:     PetscInt    i;
    610:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
    611:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
    612:       previous = next;
    613:       next     = next->next;
    614:       PetscFree(previous->string);
    615:       PetscFree(previous);
    616:     }
    617:     ascii->petsc_printfqueue       = 0;
    618:     ascii->petsc_printfqueuelength = 0;
    619:     tab = intab;
    620:     while (tab--) {
    621:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
    622:     }

    624:     va_start(Argp,format);
    625:     (*PetscVFPrintf)(fd,format,Argp);
    626:     err  = fflush(fd);
    627:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    628:     if (petsc_history) {
    629:       va_start(Argp,format);
    630:       tab = intab;
    631:       while (tab--) {
    632:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
    633:       }
    634:       (*PetscVFPrintf)(petsc_history,format,Argp);
    635:       err  = fflush(petsc_history);
    636:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    637:     }
    638:     va_end(Argp);
    639:   }
    640:   return(0);
    641: }

    643: /*@C
    644:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

    646:     Collective on PetscViewer

    648:   Input Parameters:
    649: +  viewer - the PetscViewer; either ASCII or binary
    650: -  name - the name of the file it should use

    652:     Level: advanced

    654: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
    655:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

    657: @*/
    658: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
    659: {
    661:   char           b[PETSC_MAX_PATH_LEN];

    666:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
    667:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
    668:   return(0);
    669: }

    671: /*@C
    672:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

    674:     Not Collective

    676:   Input Parameter:
    677: .  viewer - the PetscViewer; either ASCII or binary

    679:   Output Parameter:
    680: .  name - the name of the file it is using

    682:     Level: advanced

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

    686: @*/
    687: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
    688: {

    694:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
    695:   return(0);
    696: }

    698: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
    699: {
    700:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

    703:   *name = vascii->filename;
    704:   return(0);
    705: }

    707: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
    708: {
    709:   PetscErrorCode    ierr;
    710:   size_t            len;
    711:   char              fname[PETSC_MAX_PATH_LEN],*gz;
    712:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    713:   PetscBool         isstderr,isstdout;
    714:   PetscMPIInt       rank;

    717:   PetscViewerFileClose_ASCII(viewer);
    718:   if (!name) return(0);
    719:   PetscStrallocpy(name,&vascii->filename);

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

    724:   PetscStrstr(vascii->filename,".gz",&gz);
    725:   if (gz) {
    726:     PetscStrlen(gz,&len);
    727:     if (len == 3) {
    728:       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
    729:       *gz = 0;
    730:       vascii->storecompressed = PETSC_TRUE;
    731:     }
    732:   }
    733:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    734:   if (!rank) {
    735:     PetscStrcmp(name,"stderr",&isstderr);
    736:     PetscStrcmp(name,"stdout",&isstdout);
    737:     /* empty filename means stdout */
    738:     if (name[0] == 0)  isstdout = PETSC_TRUE;
    739:     if (isstderr)      vascii->fd = PETSC_STDERR;
    740:     else if (isstdout) vascii->fd = PETSC_STDOUT;
    741:     else {

    744:       PetscFixFilename(name,fname);
    745:       switch (vascii->mode) {
    746:       case FILE_MODE_READ:
    747:         vascii->fd = fopen(fname,"r");
    748:         break;
    749:       case FILE_MODE_WRITE:
    750:         vascii->fd = fopen(fname,"w");
    751:         break;
    752:       case FILE_MODE_APPEND:
    753:         vascii->fd = fopen(fname,"a");
    754:         break;
    755:       case FILE_MODE_UPDATE:
    756:         vascii->fd = fopen(fname,"r+");
    757:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    758:         break;
    759:       case FILE_MODE_APPEND_UPDATE:
    760:         /* I really want a file which is opened at the end for updating,
    761:            not a+, which opens at the beginning, but makes writes at the end.
    762:         */
    763:         vascii->fd = fopen(fname,"r+");
    764:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
    765:         else {
    766:           fseek(vascii->fd, 0, SEEK_END);
    767:         }
    768:         break;
    769:       default:
    770:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
    771:       }
    772:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
    773:     }
    774:   }
    775: #if defined(PETSC_USE_LOG)
    776:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
    777: #endif
    778:   return(0);
    779: }

    781: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
    782: {
    783:   PetscMPIInt       rank;
    784:   PetscErrorCode    ierr;
    785:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

    788:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
    789:   PetscViewerASCIIPushSynchronized(viewer);
    790:   PetscViewerCreate(subcomm,outviewer);
    791:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
    792:   PetscViewerASCIIPushSynchronized(*outviewer);
    793:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
    794:   ovascii->fd  = vascii->fd;
    795:   ovascii->tab = vascii->tab;
    796:   ovascii->closefile = PETSC_FALSE;

    798:   vascii->sviewer = *outviewer;

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

    802:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
    803:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
    804:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
    805:   return(0);
    806: }

    808: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
    809: {
    810:   PetscErrorCode    ierr;
    811:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

    817:   ascii->sviewer             = 0;
    818:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
    819:   PetscViewerDestroy(outviewer);
    820:   return(0);
    821: }

    823: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
    824: {
    825:   PetscErrorCode    ierr;
    826:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

    829:   if (ascii->filename) {
    830:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
    831:   }
    832:   return(0);
    833: }

    835: /*MC
    836:    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file

    839: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
    840:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
    841:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

    843:   Level: beginner

    845: M*/
    846: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
    847: {
    848:   PetscViewer_ASCII *vascii;
    849:   PetscErrorCode    ierr;

    852:   PetscNewLog(viewer,&vascii);
    853:   viewer->data = (void*)vascii;

    855:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
    856:   viewer->ops->flush            = PetscViewerFlush_ASCII;
    857:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
    858:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
    859:   viewer->ops->view             = PetscViewerView_ASCII;
    860:   viewer->ops->read             = PetscViewerASCIIRead;

    862:   /* defaults to stdout unless set with PetscViewerFileSetName() */
    863:   vascii->fd        = PETSC_STDOUT;
    864:   vascii->mode      = FILE_MODE_WRITE;
    865:   vascii->bviewer   = 0;
    866:   vascii->subviewer = 0;
    867:   vascii->sviewer   = 0;
    868:   vascii->tab       = 0;
    869:   vascii->tab_store = 0;
    870:   vascii->filename  = 0;
    871:   vascii->closefile = PETSC_TRUE;

    873:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
    874:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
    875:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
    876:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
    877:   return(0);
    878: }

    880: /*@C
    881:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
    882:     several processors.  Output of the first processor is followed by that of the
    883:     second, etc.

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

    887:     Input Parameters:
    888: +   viewer - the ASCII PetscViewer
    889: -   format - the usual printf() format string

    891:     Level: intermediate

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

    896:     Fortran Note:
    897:       Can only print a single character* string

    899: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
    900:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
    901:           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()

    903: @*/
    904: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
    905: {
    906:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    907:   PetscErrorCode    ierr;
    908:   PetscMPIInt       rank;
    909:   PetscInt          tab = vascii->tab;
    910:   MPI_Comm          comm;
    911:   FILE              *fp;
    912:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
    913:   int               err;

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

    922:   PetscObjectGetComm((PetscObject)viewer,&comm);
    923:   MPI_Comm_rank(comm,&rank);

    925:   if (vascii->bviewer) {
    926:     hasbviewer = PETSC_TRUE;
    927:     if (!rank) {
    928:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
    929:       PetscObjectGetComm((PetscObject)viewer,&comm);
    930:       MPI_Comm_rank(comm,&rank);
    931:     }
    932:   }

    934:   fp   = vascii->fd;

    936:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
    937:     va_list Argp;
    938:     /* flush my own messages that I may have queued up */
    939:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
    940:     PetscInt    i;
    941:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
    942:       PetscFPrintf(comm,fp,"%s",next->string);
    943:       previous = next;
    944:       next     = next->next;
    945:       PetscFree(previous->string);
    946:       PetscFree(previous);
    947:     }
    948:     vascii->petsc_printfqueue       = 0;
    949:     vascii->petsc_printfqueuelength = 0;

    951:     while (tab--) {
    952:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
    953:     }

    955:     va_start(Argp,format);
    956:     (*PetscVFPrintf)(fp,format,Argp);
    957:     err  = fflush(fp);
    958:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    959:     if (petsc_history) {
    960:       va_start(Argp,format);
    961:       (*PetscVFPrintf)(petsc_history,format,Argp);
    962:       err  = fflush(petsc_history);
    963:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
    964:     }
    965:     va_end(Argp);
    966:   } else { /* other processors add to queue */
    967:     char        *string;
    968:     va_list     Argp;
    969:     size_t      fullLength;
    970:     PrintfQueue next;

    972:     PetscNew(&next);
    973:     if (vascii->petsc_printfqueue) {
    974:       vascii->petsc_printfqueue->next = next;
    975:       vascii->petsc_printfqueue       = next;
    976:     } else {
    977:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
    978:     }
    979:     vascii->petsc_printfqueuelength++;
    980:     next->size = QUEUESTRINGSIZE;
    981:     PetscMalloc1(next->size, &next->string);
    982:     PetscMemzero(next->string,next->size);
    983:     string     = next->string;
    984:     tab       *= 2;
    985:     while (tab--) {
    986:       *string++ = ' ';
    987:     }
    988:     va_start(Argp,format);
    989:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
    990:     va_end(Argp);
    991:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
    992:       PetscFree(next->string);
    993:       next->size = fullLength + 2*vascii->tab;
    994:       PetscMalloc1(next->size, &next->string);
    995:       PetscMemzero(next->string,next->size);
    996:       string     = next->string;
    997:       tab        = 2*vascii->tab;
    998:       while (tab--) {
    999:         *string++ = ' ';
    1000:       }
    1001:       va_start(Argp,format);
    1002:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
    1003:       va_end(Argp);
    1004:     }
    1005:   }
    1006:   return(0);
    1007: }

    1009: /*@C
    1010:    PetscViewerASCIIRead - Reads from am ASCII file

    1012:    Collective on MPI_Comm

    1014:    Input Parameters:
    1015: +  viewer - the ascii viewer
    1016: .  data - location to write the data
    1017: .  num - number of items of data to read
    1018: -  datatype - type of data to read

    1020:    Output Parameters:
    1021: .  count - number of items of data actually read, or NULL

    1023:    Level: beginner

    1025:    Concepts: ascii files

    1027: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
    1028:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
    1029:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
    1030: @*/
    1031: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
    1032: {
    1033:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
    1034:   FILE              *fd = vascii->fd;
    1035:   PetscInt           i;
    1036:   int                ret = 0;

    1040:   for (i=0; i<num; i++) {
    1041:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
    1042:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
    1043:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
    1044:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
    1045:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
    1046:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
    1047: #if defined(PETSC_USE_REAL___FLOAT128)
    1048:     else if (dtype == PETSC___FLOAT128) {
    1049:       double tmp;
    1050:       ret = fscanf(fd, "%lg", &tmp);
    1051:       ((__float128*)data)[i] = tmp;
    1052:     }
    1053: #endif
    1054:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
    1055:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
    1056:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
    1057:   }
    1058:   if (count) *count = i;
    1059:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
    1060:   return(0);
    1061: }