Actual source code: filev.c

petsc-3.4.5 2014-06-29
  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,petsc_history,"  ");
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: }