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 PETSC_DLLEXPORT PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
133: {
134:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

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

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

144:     Not Collective

146: +   viewer - viewer context, obtained from PetscViewerCreate()
147: -   mode   - The file mode

149:     Level: intermediate

151:     Fortran Note:
152:     This routine is not supported in Fortran.

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

156: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
157: @*/

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

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

172: /*
173:    If petsc_history is on, then all Petsc*Printf() results are saved
174:    if the appropriate (usually .petschistory) file.
175: */

180: /*@
181:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

185:     Input Parameters:
186: +    viewer - optained with PetscViewerASCIIOpen()
187: -    tabs - number of tabs

189:     Level: developer

191:     Fortran Note:
192:     This routine is not supported in Fortran.

194:   Concepts: PetscViewerASCII^formating
195:   Concepts: tab^setting

197: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
198:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
199:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
200: @*/
201: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
202: {
203:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
204:   PetscTruth        iascii;
205:   PetscErrorCode    ierr;

209:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
210:   if (iascii) {
211:     ascii->tab = tabs;
212:   }
213:   return(0);
214: }

218: /*@
219:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
220:      lines are tabbed.

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

224:     Input Parameters:
225: .    viewer - optained with PetscViewerASCIIOpen()

227:     Level: developer

229:     Fortran Note:
230:     This routine is not supported in Fortran.

232:   Concepts: PetscViewerASCII^formating
233:   Concepts: tab^setting

235: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
236:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
237:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
238: @*/
239: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPushTab(PetscViewer viewer)
240: {
241:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
242:   PetscTruth        iascii;
243:   PetscErrorCode    ierr;

247:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
248:   if (iascii) {
249:     ascii->tab++;
250:   }
251:   return(0);
252: }

256: /*@
257:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
258:      lines are tabbed.

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

262:     Input Parameters:
263: .    viewer - optained with PetscViewerASCIIOpen()

265:     Level: developer

267:     Fortran Note:
268:     This routine is not supported in Fortran.

270:   Concepts: PetscViewerASCII^formating
271:   Concepts: tab^setting

273: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
274:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
275:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
276: @*/
277: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPopTab(PetscViewer viewer)
278: {
279:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
280:   PetscErrorCode    ierr;
281:   PetscTruth        iascii;

285:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
286:   if (iascii) {
287:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
288:     ascii->tab--;
289:   }
290:   return(0);
291: }

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

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

300:     Input Parameters:
301: +    viewer - optained with PetscViewerASCIIOpen()
302: -    flg - PETSC_YES or PETSC_NO

304:     Level: developer

306:     Fortran Note:
307:     This routine is not supported in Fortran.

309:   Concepts: PetscViewerASCII^formating
310:   Concepts: tab^setting

312: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
313:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
314:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
315: @*/
316: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
317: {
318:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
319:   PetscTruth        iascii;
320:   PetscErrorCode    ierr;

324:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
325:   if (iascii) {
326:     if (flg) {
327:       ascii->tab       = ascii->tab_store;
328:     } else {
329:       ascii->tab_store = ascii->tab;
330:       ascii->tab       = 0;
331:     }
332:   }
333:   return(0);
334: }

336: /* ----------------------------------------------------------------------- */

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

342: /*@C
343:     PetscViewerASCIIPrintf - Prints to a file, only from the first
344:     processor in the PetscViewer

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

348:     Input Parameters:
349: +    viewer - optained with PetscViewerASCIIOpen()
350: -    format - the usual printf() format string 

352:     Level: developer

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

358:   Concepts: PetscViewerASCII^printing
359:   Concepts: printing^to file
360:   Concepts: printf

362: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
363:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
364:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
365: @*/
366: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
367: {
368:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
369:   PetscMPIInt       rank;
370:   PetscInt          tab;
371:   PetscErrorCode    ierr;
372:   FILE              *fd = ascii->fd;
373:   PetscTruth        iascii;

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

381:   MPI_Comm_rank(viewer->comm,&rank);
382:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
383:   if (!rank) {
384:     va_list Argp;
385:     if (ascii->bviewer) {
386:       queuefile = fd;
387:     }

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

392:     va_start(Argp,format);
393:     PetscVFPrintf(fd,format,Argp);
394:     fflush(fd);
395:     if (petsc_history) {
396:       tab = ascii->tab;
397:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
398:       PetscVFPrintf(petsc_history,format,Argp);
399:       fflush(petsc_history);
400:     }
401:     va_end(Argp);
402:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
403:     va_list     Argp;
404:     char        *string;

406:     PrintfQueue next;
407:     PetscNew(struct _PrintfQueue,&next);
408:     if (queue) {queue->next = next; queue = next;}
409:     else       {queuebase   = queue = next;}
410:     queuelength++;
411:     string = next->string;
412:     PetscMemzero(string,QUEUESTRINGSIZE);
413:     tab = 2*ascii->tab;
414:     while (tab--) {*string++ = ' ';}
415:     va_start(Argp,format);
416:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
417:     va_end(Argp);
418:   }
419:   return(0);
420: }

424: /*@C
425:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

427:     Collective on PetscViewer

429:   Input Parameters:
430: +  viewer - the PetscViewer; either ASCII or binary
431: -  name - the name of the file it should use

433:     Level: advanced

435: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
436:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

438: @*/
439: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileSetName(PetscViewer viewer,const char name[])
440: {
441:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

446:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
447:   if (f) {
448:     (*f)(viewer,name);
449:   }
450:   return(0);
451: }

455: /*@C
456:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

458:     Not Collective

460:   Input Parameter:
461: .  viewer - the PetscViewer; either ASCII or binary

463:   Output Parameter:
464: .  name - the name of the file it is using

466:     Level: advanced

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

470: @*/
471: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileGetName(PetscViewer viewer,char **name)
472: {
473:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

477:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
478:   if (f) {
479:     (*f)(viewer,name);
480:   }
481:   return(0);
482: }

487: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
488: {
489:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

492:   *name = vascii->filename;
493:   return(0);
494: }


501: PetscErrorCode PETSC_DLLEXPORT PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
502: {
503:   PetscErrorCode    ierr;
504:   size_t            len;
505:   char              fname[PETSC_MAX_PATH_LEN],*gz;
506:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
507:   PetscTruth        isstderr,isstdout;
508:   PetscMPIInt       rank;

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

514:   /* Is this file to be compressed */
515:   vascii->storecompressed = PETSC_FALSE;
516:   PetscStrstr(vascii->filename,".gz",&gz);
517:   if (gz) {
518:     PetscStrlen(gz,&len);
519:     if (len == 3) {
520:       *gz = 0;
521:       vascii->storecompressed = PETSC_TRUE;
522:     }
523:   }
524:   MPI_Comm_rank(viewer->comm,&rank);
525:   if (!rank) {
526:     PetscStrcmp(name,"stderr",&isstderr);
527:     PetscStrcmp(name,"stdout",&isstdout);
528:     /* empty filename means stdout */
529:     if (name[0] == 0)  isstdout = PETSC_TRUE;
530:     if (isstderr)      vascii->fd = stderr;
531:     else if (isstdout) vascii->fd = stdout;
532:     else {


535:       PetscFixFilename(name,fname);
536:       switch(vascii->mode) {
537:       case FILE_MODE_READ:
538:         vascii->fd = fopen(fname,"r");
539:         break;
540:       case FILE_MODE_WRITE:
541:         vascii->fd = fopen(fname,"w");
542:         break;
543:       case FILE_MODE_APPEND:
544:         vascii->fd = fopen(fname,"a");
545:         break;
546:       case FILE_MODE_UPDATE:
547:         vascii->fd = fopen(fname,"r+");
548:         if (!vascii->fd) {
549:           vascii->fd = fopen(fname,"w+");
550:         }
551:         break;
552:       case FILE_MODE_APPEND_UPDATE:
553:         /* I really want a file which is opened at the end for updating,
554:            not a+, which opens at the beginning, but makes writes at the end.
555:         */
556:         vascii->fd = fopen(fname,"r+");
557:         if (!vascii->fd) {
558:           vascii->fd = fopen(fname,"w+");
559:         } else {
560:           fseek(vascii->fd, 0, SEEK_END);
561:         }
562:         break;
563:       default:
564:         SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
565:       }
566:       if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
567:     }
568:   }
569: #if defined(PETSC_USE_LOG)
570:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
571: #endif
572:   return(0);
573: }

578: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
579: {
580:   PetscMPIInt       rank;
581:   PetscErrorCode    ierr;
582:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
583:   const char        *name;

586:   if (vascii->sviewer) {
587:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
588:   }
589:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
590:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
591:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
592:   ovascii->fd  = vascii->fd;
593:   ovascii->tab = vascii->tab;

595:   vascii->sviewer = *outviewer;

597:   (*outviewer)->format     = viewer->format;
598:   (*outviewer)->iformat    = viewer->iformat;

600:   PetscObjectGetName((PetscObject)viewer,&name);
601:   PetscObjectSetName((PetscObject)(*outviewer),name);

603:   MPI_Comm_rank(viewer->comm,&rank);
604:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
605:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
606:   if (rank) {
607:     (*outviewer)->ops->flush = 0;
608:   } else {
609:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
610:   }
611:   return(0);
612: }

616: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
617: {
618:   PetscErrorCode    ierr;
619:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
620:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

623:   if (!ascii->sviewer) {
624:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
625:   }
626:   if (ascii->sviewer != *outviewer) {
627:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
628:   }

630:   ascii->sviewer             = 0;
631:   vascii->fd                 = stdout;
632:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
633:   PetscViewerDestroy(*outviewer);
634:   PetscViewerFlush(viewer);
635:   return(0);
636: }

641: PetscErrorCode PETSC_DLLEXPORT PetscViewerCreate_ASCII(PetscViewer viewer)
642: {
643:   PetscViewer_ASCII *vascii;
644:   PetscErrorCode    ierr;

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

650:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
651:   viewer->ops->flush            = PetscViewerFlush_ASCII;
652:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
653:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;

655:   /* defaults to stdout unless set with PetscViewerFileSetName() */
656:   vascii->fd             = stdout;
657:   vascii->mode           = FILE_MODE_WRITE;
658:   vascii->bviewer        = 0;
659:   vascii->sviewer        = 0;
660:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
661:   viewer->iformat        = 0;
662:   vascii->tab            = 0;
663:   vascii->tab_store      = 0;
664:   vascii->filename       = 0;

666:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
667:                                      PetscViewerFileSetName_ASCII);
668:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
669:                                      PetscViewerFileGetName_ASCII);
670:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
671:                                      PetscViewerFileSetMode_ASCII);

673:   return(0);
674: }


680: /*@C
681:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
682:     several processors.  Output of the first processor is followed by that of the 
683:     second, etc.

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

687:     Input Parameters:
688: +   viewer - the ASCII PetscViewer
689: -   format - the usual printf() format string 

691:     Level: intermediate

693:     Fortran Note:
694:       Can only print a single character* string

696: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
697:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
698:           PetscViewerASCIIPrintf()

700: @*/
701: PetscErrorCode PETSC_DLLEXPORT PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
702: {
703:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
704:   PetscErrorCode    ierr;
705:   PetscMPIInt       rank;
706:   PetscInt          tab = vascii->tab;
707:   MPI_Comm          comm;
708:   FILE              *fp;
709:   PetscTruth        iascii;

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

717:   comm = viewer->comm;
718:   fp   = vascii->fd;
719:   MPI_Comm_rank(comm,&rank);
720:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
721: 

723:   /* First processor prints immediately to fp */
724:   if (!rank) {
725:     va_list Argp;

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

729:     va_start(Argp,format);
730:     PetscVFPrintf(fp,format,Argp);
731:     fflush(fp);
732:     queuefile = fp;
733:     if (petsc_history) {
734:       PetscVFPrintf(petsc_history,format,Argp);
735:       fflush(petsc_history);
736:     }
737:     va_end(Argp);
738:   } else { /* other processors add to local queue */
739:     char        *string;
740:     va_list     Argp;
741:     PrintfQueue next;

743:     PetscNew(struct _PrintfQueue,&next);
744:     if (queue) {queue->next = next; queue = next;}
745:     else       {queuebase   = queue = next;}
746:     queuelength++;
747:     string = next->string;
748:     PetscMemzero(string,QUEUESTRINGSIZE);
749:     tab *= 2;
750:     while (tab--) {*string++ = ' ';}
751:     va_start(Argp,format);
752:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
753:     va_end(Argp);
754:   }
755:   return(0);
756: }