Actual source code: filev.c

  2: #include <../src/sys/viewer/impls/ascii/asciiimpl.h>  /*I     "petscsys.h"   I*/
  3: #include <stdarg.h>

  5: #define QUEUESTRINGSIZE 8192

  7: /* ----------------------------------------------------------------------*/
 10: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
 11: {
 12:   PetscMPIInt       rank;
 13:   PetscErrorCode    ierr;
 14:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 15:   PetscViewerLink   *vlink;
 16:   PetscBool         flg;
 17:   int               err;

 20:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton PetscViewer");
 21:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
 22:   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
 23:     if (vascii->fd && vascii->closefile) {
 24:       err = fclose(vascii->fd);
 25:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
 26:     }
 27:     if (vascii->storecompressed) {
 28:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
 29:       FILE *fp;
 30:       PetscStrcpy(par,"gzip ");
 31:       PetscStrcat(par,vascii->filename);
 32: #if defined(PETSC_HAVE_POPEN)
 33:       PetscPOpen(PETSC_COMM_SELF,PETSC_NULL,par,"r",&fp);
 34:       if (fgets(buf,1024,fp)) {
 35:         SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
 36:       }
 37:       PetscPClose(PETSC_COMM_SELF,fp);
 38: #else
 39:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
 40: #endif
 41:     }
 42:   }
 43:   PetscFree(vascii->filename);
 44:   PetscFree(vascii);

 46:   /* remove the viewer from the list in the MPI Communicator */
 47:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
 48:     MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
 49:   }

 51:   MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
 52:   if (flg) {
 53:     if (vlink && vlink->viewer == viewer) {
 54:       MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
 55:       PetscFree(vlink);
 56:     } else {
 57:       while (vlink && vlink->next) {
 58:         if (vlink->next->viewer == viewer) {
 59:           PetscViewerLink *nv = vlink->next;
 60:           vlink->next = vlink->next->next;
 61:           PetscFree(nv);
 62:         }
 63:         vlink = vlink->next;
 64:       }
 65:     }
 66:   }
 67:   return(0);
 68: }

 72: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 73: {
 74:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 75:   PetscErrorCode    ierr;
 77:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 78:   return(0);
 79: }

 83: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
 84: {
 85:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 86:   PetscErrorCode    ierr;
 88:   PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
 89:   return(0);
 90: }

 94: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 95: {
 96:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 97:   int               err;

100:   err = fflush(vascii->fd);
101:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
102:   return(0);
103: }

107: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
108: {
109:   PetscMPIInt       rank;
110:   PetscErrorCode    ierr;
111:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
112:   int               err;

115:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
116:   /* fflush() fails on OSX for read-only descriptors */
117:   if (!rank && (vascii->mode != FILE_MODE_READ)) {
118:     err = fflush(vascii->fd);
119:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
120:   }

122:   if (vascii->allowsynchronized) {
123:     /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf()  */
124:     PetscSynchronizedFlush(((PetscObject)viewer)->comm);
125:   }
126:   return(0);
127: }

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

134:     Not Collective

136: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
137: -   fd - file pointer

139:     Level: intermediate

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

144:   Concepts: PetscViewer^file pointer
145:   Concepts: file pointer^getting from PetscViewer

147: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
148:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
149: @*/
150: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
151: {
152:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

155:   *fd = vascii->fd;
156:   return(0);
157: }

162: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
163: {
164:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

167:   *mode = vascii->mode;
168:   return(0);
169: }

172: /*@C
173:     PetscViewerFileSetMode - Sets the mode in which to open the file.

175:     Not Collective

177: +   viewer - viewer context, obtained from PetscViewerCreate()
178: -   mode   - The file mode

180:     Level: intermediate

182:     Fortran Note:
183:     This routine is not supported in Fortran.

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

187: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
188: @*/

193: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
194: {
195:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

198:   vascii->mode = mode;
199:   return(0);
200: }

203: /*
204:    If petsc_history is on, then all Petsc*Printf() results are saved
205:    if the appropriate (usually .petschistory) file.
206: */

211: /*@
212:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

216:     Input Parameters:
217: +    viewer - optained with PetscViewerASCIIOpen()
218: -    tabs - number of tabs

220:     Level: developer

222:     Fortran Note:
223:     This routine is not supported in Fortran.

225:   Concepts: PetscViewerASCII^formating
226:   Concepts: tab^setting

228: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
229:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
230:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
231: @*/
232: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
233: {
234:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
235:   PetscBool         iascii;
236:   PetscErrorCode    ierr;

240:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
241:   if (iascii) {
242:     ascii->tab = tabs;
243:   }
244:   return(0);
245: }

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

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

254:     Input Parameters:
255: +    viewer - optained with PetscViewerASCIIOpen()
256: -    tabs - number of tabs

258:     Level: developer

260:     Fortran Note:
261:     This routine is not supported in Fortran.

263:   Concepts: PetscViewerASCII^formating
264:   Concepts: tab^setting

266: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
267:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
268:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
269: @*/
270: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
271: {
272:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
273:   PetscBool         iascii;
274:   PetscErrorCode    ierr;

278:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
279:   if (iascii) {
280:     ascii->tab += tabs;
281:   }
282:   return(0);
283: }

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

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

292:     Input Parameters:
293: +    viewer - optained with PetscViewerASCIIOpen()
294: -    tabs - number of tabs

296:     Level: developer

298:     Fortran Note:
299:     This routine is not supported in Fortran.

301:   Concepts: PetscViewerASCII^formating
302:   Concepts: tab^setting

304: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
305:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
306:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
307: @*/
308: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
309: {
310:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
311:   PetscBool         iascii;
312:   PetscErrorCode    ierr;

316:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
317:   if (iascii) {
318:     ascii->tab -= tabs;
319:   }
320:   return(0);
321: }

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

328:     Collective on PetscViewer

330:     Input Parameters:
331: +    viewer - optained with PetscViewerASCIIOpen()
332: -    allow - PETSC_TRUE to allow the synchronized printing

334:     Level: intermediate

336:   Concepts: PetscViewerASCII^formating
337:   Concepts: tab^setting

339: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
340:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
341:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
342: @*/
343: PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
344: {
345:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
346:   PetscBool         iascii;
347:   PetscErrorCode    ierr;

351:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
352:   if (iascii) {
353:     ascii->allowsynchronized = allow;
354:   }
355:   return(0);
356: }

360: /*@
361:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
362:      lines are tabbed.

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

366:     Input Parameters:
367: .    viewer - optained with PetscViewerASCIIOpen()

369:     Level: developer

371:     Fortran Note:
372:     This routine is not supported in Fortran.

374:   Concepts: PetscViewerASCII^formating
375:   Concepts: tab^setting

377: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
378:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
379:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
380: @*/
381: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
382: {
383:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
384:   PetscBool         iascii;
385:   PetscErrorCode    ierr;

389:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
390:   if (iascii) {
391:     ascii->tab++;
392:   }
393:   return(0);
394: }

398: /*@
399:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
400:      lines are tabbed.

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

404:     Input Parameters:
405: .    viewer - optained with PetscViewerASCIIOpen()

407:     Level: developer

409:     Fortran Note:
410:     This routine is not supported in Fortran.

412:   Concepts: PetscViewerASCII^formating
413:   Concepts: tab^setting

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

427:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
428:   if (iascii) {
429:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
430:     ascii->tab--;
431:   }
432:   return(0);
433: }

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

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

442:     Input Parameters:
443: +    viewer - optained with PetscViewerASCIIOpen()
444: -    flg - PETSC_TRUE or PETSC_FALSE

446:     Level: developer

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

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

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

466:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
467:   if (iascii) {
468:     if (flg) {
469:       ascii->tab       = ascii->tab_store;
470:     } else {
471:       ascii->tab_store = ascii->tab;
472:       ascii->tab       = 0;
473:     }
474:   }
475:   return(0);
476: }

478: /* ----------------------------------------------------------------------- */

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

484: /*@C
485:     PetscViewerASCIIPrintf - Prints to a file, only from the first
486:     processor in the PetscViewer

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

490:     Input Parameters:
491: +    viewer - optained with PetscViewerASCIIOpen()
492: -    format - the usual printf() format string 

494:     Level: developer

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

500:   Concepts: PetscViewerASCII^printing
501:   Concepts: printing^to file
502:   Concepts: printf

504: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
505:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
506:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
507: @*/
508: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
509: {
510:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
511:   PetscMPIInt       rank;
512:   PetscInt          tab;
513:   PetscErrorCode    ierr;
514:   FILE              *fd = ascii->fd;
515:   PetscBool         iascii;
516:   int               err;

521:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
522:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

524:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
525:   if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
526:   if (!rank) {
527:     va_list Argp;
528:     if (ascii->bviewer) {
529:       queuefile = fd;
530:     }

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

535:     va_start(Argp,format);
536:     PetscVFPrintf(fd,format,Argp);
537:     err = fflush(fd);
538:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
539:     if (petsc_history) {
540:       va_start(Argp,format);
541:       tab = ascii->tab;
542:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
543:       (*PetscVFPrintf)(petsc_history,format,Argp);
544:       err = fflush(petsc_history);
545:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
546:     }
547:     va_end(Argp);
548:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
549:     va_list     Argp;
550:     size_t      fullLength;
551:     char        *string;

553:     PrintfQueue next;
554:     PetscNew(struct _PrintfQueue,&next);
555:     if (queue) {queue->next = next; queue = next;}
556:     else       {queuebase   = queue = next;}
557:     queuelength++;
558:     next->size = QUEUESTRINGSIZE;
559:     PetscMalloc(next->size*sizeof(char), &next->string);
560:     PetscMemzero(next->string,next->size);
561:     string = next->string;
562:     tab = 2*ascii->tab;
563:     while (tab--) {*string++ = ' ';}
564:     va_start(Argp,format);
565:     PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
566:     va_end(Argp);
567:   }
568:   return(0);
569: }

573: /*@C
574:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

576:     Collective on PetscViewer

578:   Input Parameters:
579: +  viewer - the PetscViewer; either ASCII or binary
580: -  name - the name of the file it should use

582:     Level: advanced

584: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
585:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

587: @*/
588: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
589: {

595:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
596:   return(0);
597: }

601: /*@C
602:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

604:     Not Collective

606:   Input Parameter:
607: .  viewer - the PetscViewer; either ASCII or binary

609:   Output Parameter:
610: .  name - the name of the file it is using

612:     Level: advanced

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

616: @*/
617: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
618: {

623:   PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
624:   return(0);
625: }

630: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
631: {
632:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

635:   *name = vascii->filename;
636:   return(0);
637: }


644: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
645: {
646:   PetscErrorCode    ierr;
647:   size_t            len;
648:   char              fname[PETSC_MAX_PATH_LEN],*gz;
649:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
650:   PetscBool         isstderr,isstdout;
651:   PetscMPIInt       rank;

654:   if (!name) return(0);
655:   PetscFree(vascii->filename);
656:   PetscStrallocpy(name,&vascii->filename);

658:   /* Is this file to be compressed */
659:   vascii->storecompressed = PETSC_FALSE;
660:   PetscStrstr(vascii->filename,".gz",&gz);
661:   if (gz) {
662:     PetscStrlen(gz,&len);
663:     if (len == 3) {
664:       *gz = 0;
665:       vascii->storecompressed = PETSC_TRUE;
666:     }
667:   }
668:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
669:   if (!rank) {
670:     PetscStrcmp(name,"stderr",&isstderr);
671:     PetscStrcmp(name,"stdout",&isstdout);
672:     /* empty filename means stdout */
673:     if (name[0] == 0)  isstdout = PETSC_TRUE;
674:     if (isstderr)      vascii->fd = PETSC_STDERR;
675:     else if (isstdout) vascii->fd = PETSC_STDOUT;
676:     else {


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

722: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
723: {
724:   PetscMPIInt       rank;
725:   PetscErrorCode    ierr;
726:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
727:   const char        *name;

730:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
731:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
732:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
733:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
734:   ovascii->fd  = vascii->fd;
735:   ovascii->tab = vascii->tab;

737:   vascii->sviewer = *outviewer;

739:   (*outviewer)->format     = viewer->format;
740:   (*outviewer)->iformat    = viewer->iformat;

742:   PetscObjectGetName((PetscObject)viewer,&name);
743:   PetscObjectSetName((PetscObject)(*outviewer),name);

745:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
746:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
747:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
748:   if (rank) {
749:     (*outviewer)->ops->flush = 0;
750:   } else {
751:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
752:   }
753:   return(0);
754: }

758: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
759: {
760:   PetscErrorCode    ierr;
761:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
762:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

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

768:   ascii->sviewer             = 0;
769:   vascii->fd                 = PETSC_STDOUT;
770:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
771:   PetscViewerDestroy(outviewer);
772:   PetscViewerFlush(viewer);
773:   return(0);
774: }

778: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
779: {
780:   PetscMPIInt       rank;
781:   PetscErrorCode    ierr;
782:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
783:   const char        *name;

786:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
787:   /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
788:   PetscViewerCreate(subcomm,outviewer);
789:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
790:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
791:   ovascii->fd  = vascii->fd;
792:   ovascii->tab = vascii->tab;

794:   vascii->sviewer = *outviewer;

796:   (*outviewer)->format     = viewer->format;
797:   (*outviewer)->iformat    = viewer->iformat;

799:   PetscObjectGetName((PetscObject)viewer,&name);
800:   PetscObjectSetName((PetscObject)(*outviewer),name);

802:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
803:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
804:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
805:   /* following might not be correct??? */
806:   if (rank) {
807:     (*outviewer)->ops->flush = 0;
808:   } else {
809:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
810:   }
811:   return(0);
812: }

816: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
817: {
818:   PetscErrorCode    ierr;
819:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
820:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

823:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
824:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");

826:   ascii->sviewer             = 0;
827:   vascii->fd                 = PETSC_STDOUT;
828:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
829:   PetscViewerDestroy(outviewer);
830:   PetscViewerFlush(viewer);
831:   return(0);
832: }

837: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
838: {
839:   PetscViewer_ASCII *vascii;
840:   PetscErrorCode    ierr;

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

846:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
847:   viewer->ops->flush            = PetscViewerFlush_ASCII;
848:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
849:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
850:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
851:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;

853:   /* defaults to stdout unless set with PetscViewerFileSetName() */
854:   vascii->fd             = PETSC_STDOUT;
855:   vascii->mode           = FILE_MODE_WRITE;
856:   vascii->bviewer        = 0;
857:   vascii->sviewer        = 0;
858:   viewer->format         = PETSC_VIEWER_DEFAULT;
859:   viewer->iformat        = 0;
860:   vascii->tab            = 0;
861:   vascii->tab_store      = 0;
862:   vascii->filename       = 0;
863:   vascii->closefile      = PETSC_TRUE;

865:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
866:                                      PetscViewerFileSetName_ASCII);
867:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
868:                                      PetscViewerFileGetName_ASCII);
869:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
870:                                      PetscViewerFileGetMode_ASCII);
871:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
872:                                      PetscViewerFileSetMode_ASCII);

874:   return(0);
875: }


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

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

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

892:     Level: intermediate

894:     Notes: 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(), PetscViewerASCIISynchronizedAllow()

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

918:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
919:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
920:   MPI_Comm_size(((PetscObject)viewer)->comm,&size);
921:   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");

923:   comm = ((PetscObject)viewer)->comm;
924:   fp   = vascii->fd;
925:   MPI_Comm_rank(comm,&rank);
926:   if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
927: 

929:   /* First processor prints immediately to fp */
930:   if (!rank) {
931:     va_list Argp;

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

935:     va_start(Argp,format);
936:     (*PetscVFPrintf)(fp,format,Argp);
937:     err = fflush(fp);
938:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
939:     queuefile = fp;
940:     if (petsc_history) {
941:       va_start(Argp,format);
942:       (*PetscVFPrintf)(petsc_history,format,Argp);
943:       err = fflush(petsc_history);
944:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
945:     }
946:     va_end(Argp);
947:   } else { /* other processors add to local queue */
948:     char        *string;
949:     va_list     Argp;
950:     size_t      fullLength;
951:     PrintfQueue next;

953:     PetscNew(struct _PrintfQueue,&next);
954:     if (queue) {queue->next = next; queue = next;}
955:     else       {queuebase   = queue = next;}
956:     queuelength++;
957:     next->size = QUEUESTRINGSIZE;
958:     PetscMalloc(next->size*sizeof(char), &next->string);
959:     PetscMemzero(next->string,next->size);
960:     string = next->string;
961:     tab *= 2;
962:     while (tab--) {*string++ = ' ';}
963:     va_start(Argp,format);
964:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
965:     va_end(Argp);
966:   }
967:   return(0);
968: }