Actual source code: filev.c

  1: #define PETSC_DLL

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

  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:   PetscTruth        flg;

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

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

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

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

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

 86:   fflush(vascii->fd);
 87:   return(0);
 88: }

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

 99:   MPI_Comm_rank(viewer->comm,&rank);
100:   if (!rank) {
101:     fflush(vascii->fd);
102:   }

104:   /*
105:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
106:   */
107:   PetscSynchronizedFlush(viewer->comm);
108:   return(0);
109: }

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

116:     Not Collective

118: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
119: -   fd - file pointer

121:     Level: intermediate

123:     Fortran Note:
124:     This routine is not supported in Fortran.

126:   Concepts: PetscViewer^file pointer
127:   Concepts: file pointer^getting from PetscViewer

129: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
130:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
131: @*/
132: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
133: {
134:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

137:   *fd = vascii->fd;
138:   return(0);
139: }

144: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
145: {
146:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

149:   *mode = vascii->mode;
150:   return(0);
151: }

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

157:     Not Collective

159: +   viewer - viewer context, obtained from PetscViewerCreate()
160: -   mode   - The file mode

162:     Level: intermediate

164:     Fortran Note:
165:     This routine is not supported in Fortran.

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

169: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
170: @*/

175: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
176: {
177:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

180:   vascii->mode = mode;
181:   return(0);
182: }

185: /*
186:    If petsc_history is on, then all Petsc*Printf() results are saved
187:    if the appropriate (usually .petschistory) file.
188: */

193: /*@
194:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

198:     Input Parameters:
199: +    viewer - optained with PetscViewerASCIIOpen()
200: -    tabs - number of tabs

202:     Level: developer

204:     Fortran Note:
205:     This routine is not supported in Fortran.

207:   Concepts: PetscViewerASCII^formating
208:   Concepts: tab^setting

210: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
211:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
212:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
213: @*/
214: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
215: {
216:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
217:   PetscTruth        iascii;
218:   PetscErrorCode    ierr;

222:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
223:   if (iascii) {
224:     ascii->tab = tabs;
225:   }
226:   return(0);
227: }

231: /*@
232:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
233:      lines are tabbed.

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

237:     Input Parameters:
238: .    viewer - optained with PetscViewerASCIIOpen()

240:     Level: developer

242:     Fortran Note:
243:     This routine is not supported in Fortran.

245:   Concepts: PetscViewerASCII^formating
246:   Concepts: tab^setting

248: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
249:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
250:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
251: @*/
252: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
253: {
254:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
255:   PetscTruth        iascii;
256:   PetscErrorCode    ierr;

260:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
261:   if (iascii) {
262:     ascii->tab++;
263:   }
264:   return(0);
265: }

269: /*@
270:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
271:      lines are tabbed.

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

275:     Input Parameters:
276: .    viewer - optained with PetscViewerASCIIOpen()

278:     Level: developer

280:     Fortran Note:
281:     This routine is not supported in Fortran.

283:   Concepts: PetscViewerASCII^formating
284:   Concepts: tab^setting

286: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
287:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
288:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
289: @*/
290: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
291: {
292:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
293:   PetscErrorCode    ierr;
294:   PetscTruth        iascii;

298:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
299:   if (iascii) {
300:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
301:     ascii->tab--;
302:   }
303:   return(0);
304: }

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

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

313:     Input Parameters:
314: +    viewer - optained with PetscViewerASCIIOpen()
315: -    flg - PETSC_YES or PETSC_NO

317:     Level: developer

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

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

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

337:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
338:   if (iascii) {
339:     if (flg) {
340:       ascii->tab       = ascii->tab_store;
341:     } else {
342:       ascii->tab_store = ascii->tab;
343:       ascii->tab       = 0;
344:     }
345:   }
346:   return(0);
347: }

349: /* ----------------------------------------------------------------------- */

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

355: /*@C
356:     PetscViewerASCIIPrintf - Prints to a file, only from the first
357:     processor in the PetscViewer

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

361:     Input Parameters:
362: +    viewer - optained with PetscViewerASCIIOpen()
363: -    format - the usual printf() format string 

365:     Level: developer

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

371:   Concepts: PetscViewerASCII^printing
372:   Concepts: printing^to file
373:   Concepts: printf

375: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
376:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
377:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
378: @*/
379: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
380: {
381:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
382:   PetscMPIInt       rank;
383:   PetscInt          tab;
384:   PetscErrorCode    ierr;
385:   FILE              *fd = ascii->fd;
386:   PetscTruth        iascii;

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

394:   MPI_Comm_rank(viewer->comm,&rank);
395:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
396:   if (!rank) {
397:     va_list Argp;
398:     if (ascii->bviewer) {
399:       queuefile = fd;
400:     }

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

405:     va_start(Argp,format);
406:     PetscVFPrintf(fd,format,Argp);
407:     fflush(fd);
408:     if (petsc_history) {
409:       tab = ascii->tab;
410:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
411:       PetscVFPrintf(petsc_history,format,Argp);
412:       fflush(petsc_history);
413:     }
414:     va_end(Argp);
415:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
416:     va_list     Argp;
417:     char        *string;

419:     PrintfQueue next;
420:     PetscNew(struct _PrintfQueue,&next);
421:     if (queue) {queue->next = next; queue = next;}
422:     else       {queuebase   = queue = next;}
423:     queuelength++;
424:     string = next->string;
425:     PetscMemzero(string,QUEUESTRINGSIZE);
426:     tab = 2*ascii->tab;
427:     while (tab--) {*string++ = ' ';}
428:     va_start(Argp,format);
429:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
430:     va_end(Argp);
431:   }
432:   return(0);
433: }

437: /*@C
438:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

440:     Collective on PetscViewer

442:   Input Parameters:
443: +  viewer - the PetscViewer; either ASCII or binary
444: -  name - the name of the file it should use

446:     Level: advanced

448: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
449:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

451: @*/
452: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
453: {
454:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

459:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
460:   if (f) {
461:     (*f)(viewer,name);
462:   }
463:   return(0);
464: }

468: /*@C
469:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

471:     Not Collective

473:   Input Parameter:
474: .  viewer - the PetscViewer; either ASCII or binary

476:   Output Parameter:
477: .  name - the name of the file it is using

479:     Level: advanced

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

483: @*/
484: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,char **name)
485: {
486:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

490:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
491:   if (f) {
492:     (*f)(viewer,name);
493:   }
494:   return(0);
495: }

500: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
501: {
502:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

505:   *name = vascii->filename;
506:   return(0);
507: }


514: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
515: {
516:   PetscErrorCode    ierr;
517:   size_t            len;
518:   char              fname[PETSC_MAX_PATH_LEN],*gz;
519:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
520:   PetscTruth        isstderr,isstdout;
521:   PetscMPIInt       rank;

524:   if (!name) return(0);
525:   PetscStrallocpy(name,&vascii->filename);

527:   /* Is this file to be compressed */
528:   vascii->storecompressed = PETSC_FALSE;
529:   PetscStrstr(vascii->filename,".gz",&gz);
530:   if (gz) {
531:     PetscStrlen(gz,&len);
532:     if (len == 3) {
533:       *gz = 0;
534:       vascii->storecompressed = PETSC_TRUE;
535:     }
536:   }
537:   MPI_Comm_rank(viewer->comm,&rank);
538:   if (!rank) {
539:     PetscStrcmp(name,"stderr",&isstderr);
540:     PetscStrcmp(name,"stdout",&isstdout);
541:     /* empty filename means stdout */
542:     if (name[0] == 0)  isstdout = PETSC_TRUE;
543:     if (isstderr)      vascii->fd = stderr;
544:     else if (isstdout) vascii->fd = stdout;
545:     else {


548:       PetscFixFilename(name,fname);
549:       switch(vascii->mode) {
550:       case FILE_MODE_READ:
551:         vascii->fd = fopen(fname,"r");
552:         break;
553:       case FILE_MODE_WRITE:
554:         vascii->fd = fopen(fname,"w");
555:         break;
556:       case FILE_MODE_APPEND:
557:         vascii->fd = fopen(fname,"a");
558:         break;
559:       case FILE_MODE_UPDATE:
560:         vascii->fd = fopen(fname,"r+");
561:         if (!vascii->fd) {
562:           vascii->fd = fopen(fname,"w+");
563:         }
564:         break;
565:       case FILE_MODE_APPEND_UPDATE:
566:         /* I really want a file which is opened at the end for updating,
567:            not a+, which opens at the beginning, but makes writes at the end.
568:         */
569:         vascii->fd = fopen(fname,"r+");
570:         if (!vascii->fd) {
571:           vascii->fd = fopen(fname,"w+");
572:         } else {
573:           fseek(vascii->fd, 0, SEEK_END);
574:         }
575:         break;
576:       default:
577:         SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
578:       }
579:       if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
580:     }
581:   }
582: #if defined(PETSC_USE_LOG)
583:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
584: #endif
585:   return(0);
586: }

591: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
592: {
593:   PetscMPIInt       rank;
594:   PetscErrorCode    ierr;
595:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
596:   const char        *name;

599:   if (vascii->sviewer) {
600:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
601:   }
602:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
603:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
604:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
605:   ovascii->fd  = vascii->fd;
606:   ovascii->tab = vascii->tab;

608:   vascii->sviewer = *outviewer;

610:   (*outviewer)->format     = viewer->format;
611:   (*outviewer)->iformat    = viewer->iformat;

613:   PetscObjectGetName((PetscObject)viewer,&name);
614:   PetscObjectSetName((PetscObject)(*outviewer),name);

616:   MPI_Comm_rank(viewer->comm,&rank);
617:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
618:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
619:   if (rank) {
620:     (*outviewer)->ops->flush = 0;
621:   } else {
622:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
623:   }
624:   return(0);
625: }

629: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
630: {
631:   PetscErrorCode    ierr;
632:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
633:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

636:   if (!ascii->sviewer) {
637:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
638:   }
639:   if (ascii->sviewer != *outviewer) {
640:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
641:   }

643:   ascii->sviewer             = 0;
644:   vascii->fd                 = stdout;
645:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
646:   PetscViewerDestroy(*outviewer);
647:   PetscViewerFlush(viewer);
648:   return(0);
649: }

654: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
655: {
656:   PetscViewer_ASCII *vascii;
657:   PetscErrorCode    ierr;

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

663:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
664:   viewer->ops->flush            = PetscViewerFlush_ASCII;
665:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
666:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

668:   /* defaults to stdout unless set with PetscViewerFileSetName() */
669:   vascii->fd             = stdout;
670:   vascii->mode           = FILE_MODE_WRITE;
671:   vascii->bviewer        = 0;
672:   vascii->sviewer        = 0;
673:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
674:   viewer->iformat        = 0;
675:   vascii->tab            = 0;
676:   vascii->tab_store      = 0;
677:   vascii->filename       = 0;

679:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
680:                                      PetscViewerFileSetName_ASCII);
681:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
682:                                      PetscViewerFileGetName_ASCII);
683:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
684:                                      PetscViewerFileGetMode_ASCII);
685:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
686:                                      PetscViewerFileSetMode_ASCII);

688:   return(0);
689: }


695: /*@C
696:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
697:     several processors.  Output of the first processor is followed by that of the 
698:     second, etc.

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

702:     Input Parameters:
703: +   viewer - the ASCII PetscViewer
704: -   format - the usual printf() format string 

706:     Level: intermediate

708:     Fortran Note:
709:       Can only print a single character* string

711: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
712:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
713:           PetscViewerASCIIPrintf()

715: @*/
716: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
717: {
718:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
719:   PetscErrorCode    ierr;
720:   PetscMPIInt       rank;
721:   PetscInt          tab = vascii->tab;
722:   MPI_Comm          comm;
723:   FILE              *fp;
724:   PetscTruth        iascii;

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

732:   comm = viewer->comm;
733:   fp   = vascii->fd;
734:   MPI_Comm_rank(comm,&rank);
735:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
736: 

738:   /* First processor prints immediately to fp */
739:   if (!rank) {
740:     va_list Argp;

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

744:     va_start(Argp,format);
745:     PetscVFPrintf(fp,format,Argp);
746:     fflush(fp);
747:     queuefile = fp;
748:     if (petsc_history) {
749:       PetscVFPrintf(petsc_history,format,Argp);
750:       fflush(petsc_history);
751:     }
752:     va_end(Argp);
753:   } else { /* other processors add to local queue */
754:     char        *string;
755:     va_list     Argp;
756:     PrintfQueue next;

758:     PetscNew(struct _PrintfQueue,&next);
759:     if (queue) {queue->next = next; queue = next;}
760:     else       {queuebase   = queue = next;}
761:     queuelength++;
762:     string = next->string;
763:     PetscMemzero(string,QUEUESTRINGSIZE);
764:     tab *= 2;
765:     while (tab--) {*string++ = ' ';}
766:     va_start(Argp,format);
767:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
768:     va_end(Argp);
769:   }
770:   return(0);
771: }