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 PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
 82: {
 83:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 84:   PetscErrorCode    ierr;
 86:   PetscViewerRestoreSubcomm(vascii->bviewer,viewer->comm,&viewer);
 87:   return(0);
 88: }

 92: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 93: {
 94:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

 97:   fflush(vascii->fd);
 98:   return(0);
 99: }

103: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
104: {
105:   PetscMPIInt       rank;
106:   PetscErrorCode    ierr;
107:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

110:   MPI_Comm_rank(viewer->comm,&rank);
111:   if (!rank) {
112:     fflush(vascii->fd);
113:   }

115:   /*
116:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
117:   */
118:   PetscSynchronizedFlush(viewer->comm);
119:   return(0);
120: }

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

127:     Not Collective

129: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
130: -   fd - file pointer

132:     Level: intermediate

134:     Fortran Note:
135:     This routine is not supported in Fortran.

137:   Concepts: PetscViewer^file pointer
138:   Concepts: file pointer^getting from PetscViewer

140: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
141:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
142: @*/
143: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
144: {
145:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

148:   *fd = vascii->fd;
149:   return(0);
150: }

155: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
156: {
157:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

160:   *mode = vascii->mode;
161:   return(0);
162: }

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

168:     Not Collective

170: +   viewer - viewer context, obtained from PetscViewerCreate()
171: -   mode   - The file mode

173:     Level: intermediate

175:     Fortran Note:
176:     This routine is not supported in Fortran.

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

180: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
181: @*/

186: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
187: {
188:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

191:   vascii->mode = mode;
192:   return(0);
193: }

196: /*
197:    If petsc_history is on, then all Petsc*Printf() results are saved
198:    if the appropriate (usually .petschistory) file.
199: */

204: /*@
205:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

209:     Input Parameters:
210: +    viewer - optained with PetscViewerASCIIOpen()
211: -    tabs - number of tabs

213:     Level: developer

215:     Fortran Note:
216:     This routine is not supported in Fortran.

218:   Concepts: PetscViewerASCII^formating
219:   Concepts: tab^setting

221: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
222:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
223:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
224: @*/
225: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
226: {
227:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
228:   PetscTruth        iascii;
229:   PetscErrorCode    ierr;

233:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
234:   if (iascii) {
235:     ascii->tab = tabs;
236:   }
237:   return(0);
238: }

242: /*@
243:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
244:      lines are tabbed.

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

248:     Input Parameters:
249: .    viewer - optained with PetscViewerASCIIOpen()

251:     Level: developer

253:     Fortran Note:
254:     This routine is not supported in Fortran.

256:   Concepts: PetscViewerASCII^formating
257:   Concepts: tab^setting

259: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
260:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
261:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
262: @*/
263: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
264: {
265:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
266:   PetscTruth        iascii;
267:   PetscErrorCode    ierr;

271:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
272:   if (iascii) {
273:     ascii->tab++;
274:   }
275:   return(0);
276: }

280: /*@
281:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
282:      lines are tabbed.

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

286:     Input Parameters:
287: .    viewer - optained with PetscViewerASCIIOpen()

289:     Level: developer

291:     Fortran Note:
292:     This routine is not supported in Fortran.

294:   Concepts: PetscViewerASCII^formating
295:   Concepts: tab^setting

297: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
298:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
299:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
300: @*/
301: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
302: {
303:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
304:   PetscErrorCode    ierr;
305:   PetscTruth        iascii;

309:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
310:   if (iascii) {
311:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
312:     ascii->tab--;
313:   }
314:   return(0);
315: }

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

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

324:     Input Parameters:
325: +    viewer - optained with PetscViewerASCIIOpen()
326: -    flg - PETSC_YES or PETSC_NO

328:     Level: developer

330:     Fortran Note:
331:     This routine is not supported in Fortran.

333:   Concepts: PetscViewerASCII^formating
334:   Concepts: tab^setting

336: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
337:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
338:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
339: @*/
340: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
341: {
342:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
343:   PetscTruth        iascii;
344:   PetscErrorCode    ierr;

348:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
349:   if (iascii) {
350:     if (flg) {
351:       ascii->tab       = ascii->tab_store;
352:     } else {
353:       ascii->tab_store = ascii->tab;
354:       ascii->tab       = 0;
355:     }
356:   }
357:   return(0);
358: }

360: /* ----------------------------------------------------------------------- */

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

366: /*@C
367:     PetscViewerASCIIPrintf - Prints to a file, only from the first
368:     processor in the PetscViewer

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

372:     Input Parameters:
373: +    viewer - optained with PetscViewerASCIIOpen()
374: -    format - the usual printf() format string 

376:     Level: developer

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

382:   Concepts: PetscViewerASCII^printing
383:   Concepts: printing^to file
384:   Concepts: printf

386: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
387:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
388:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
389: @*/
390: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
391: {
392:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
393:   PetscMPIInt       rank;
394:   PetscInt          tab;
395:   PetscErrorCode    ierr;
396:   FILE              *fd = ascii->fd;
397:   PetscTruth        iascii;

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

405:   MPI_Comm_rank(viewer->comm,&rank);
406:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
407:   if (!rank) {
408:     va_list Argp;
409:     if (ascii->bviewer) {
410:       queuefile = fd;
411:     }

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

416:     va_start(Argp,format);
417:     PetscVFPrintf(fd,format,Argp);
418:     fflush(fd);
419:     if (petsc_history) {
420:       tab = ascii->tab;
421:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
422:       PetscVFPrintf(petsc_history,format,Argp);
423:       fflush(petsc_history);
424:     }
425:     va_end(Argp);
426:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
427:     va_list     Argp;
428:     char        *string;

430:     PrintfQueue next;
431:     PetscNew(struct _PrintfQueue,&next);
432:     if (queue) {queue->next = next; queue = next;}
433:     else       {queuebase   = queue = next;}
434:     queuelength++;
435:     string = next->string;
436:     PetscMemzero(string,QUEUESTRINGSIZE);
437:     tab = 2*ascii->tab;
438:     while (tab--) {*string++ = ' ';}
439:     va_start(Argp,format);
440:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
441:     va_end(Argp);
442:   }
443:   return(0);
444: }

448: /*@C
449:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

451:     Collective on PetscViewer

453:   Input Parameters:
454: +  viewer - the PetscViewer; either ASCII or binary
455: -  name - the name of the file it should use

457:     Level: advanced

459: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
460:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

462: @*/
463: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
464: {
465:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

470:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
471:   if (f) {
472:     (*f)(viewer,name);
473:   }
474:   return(0);
475: }

479: /*@C
480:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

482:     Not Collective

484:   Input Parameter:
485: .  viewer - the PetscViewer; either ASCII or binary

487:   Output Parameter:
488: .  name - the name of the file it is using

490:     Level: advanced

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

494: @*/
495: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,char **name)
496: {
497:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

501:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
502:   if (f) {
503:     (*f)(viewer,name);
504:   }
505:   return(0);
506: }

511: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
512: {
513:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

516:   *name = vascii->filename;
517:   return(0);
518: }


525: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
526: {
527:   PetscErrorCode    ierr;
528:   size_t            len;
529:   char              fname[PETSC_MAX_PATH_LEN],*gz;
530:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
531:   PetscTruth        isstderr,isstdout;
532:   PetscMPIInt       rank;

535:   if (!name) return(0);
536:   PetscStrfree(vascii->filename);
537:   PetscStrallocpy(name,&vascii->filename);

539:   /* Is this file to be compressed */
540:   vascii->storecompressed = PETSC_FALSE;
541:   PetscStrstr(vascii->filename,".gz",&gz);
542:   if (gz) {
543:     PetscStrlen(gz,&len);
544:     if (len == 3) {
545:       *gz = 0;
546:       vascii->storecompressed = PETSC_TRUE;
547:     }
548:   }
549:   MPI_Comm_rank(viewer->comm,&rank);
550:   if (!rank) {
551:     PetscStrcmp(name,"stderr",&isstderr);
552:     PetscStrcmp(name,"stdout",&isstdout);
553:     /* empty filename means stdout */
554:     if (name[0] == 0)  isstdout = PETSC_TRUE;
555:     if (isstderr)      vascii->fd = stderr;
556:     else if (isstdout) vascii->fd = stdout;
557:     else {


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

603: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
604: {
605:   PetscMPIInt       rank;
606:   PetscErrorCode    ierr;
607:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
608:   const char        *name;

611:   if (vascii->sviewer) {
612:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
613:   }
614:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
615:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
616:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
617:   ovascii->fd  = vascii->fd;
618:   ovascii->tab = vascii->tab;

620:   vascii->sviewer = *outviewer;

622:   (*outviewer)->format     = viewer->format;
623:   (*outviewer)->iformat    = viewer->iformat;

625:   PetscObjectGetName((PetscObject)viewer,&name);
626:   PetscObjectSetName((PetscObject)(*outviewer),name);

628:   MPI_Comm_rank(viewer->comm,&rank);
629:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
630:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
631:   if (rank) {
632:     (*outviewer)->ops->flush = 0;
633:   } else {
634:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
635:   }
636:   return(0);
637: }

641: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
642: {
643:   PetscErrorCode    ierr;
644:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
645:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

648:   if (!ascii->sviewer) {
649:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
650:   }
651:   if (ascii->sviewer != *outviewer) {
652:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
653:   }

655:   ascii->sviewer             = 0;
656:   vascii->fd                 = stdout;
657:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
658:   PetscViewerDestroy(*outviewer);
659:   PetscViewerFlush(viewer);
660:   return(0);
661: }

665: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
666: {
667:   PetscMPIInt       rank;
668:   PetscErrorCode    ierr;
669:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
670:   const char        *name;

673:   if (vascii->sviewer) {
674:     SETERRQ(PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
675:   }
676:   /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
677:   PetscViewerCreate(subcomm,outviewer);
678:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
679:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
680:   ovascii->fd  = vascii->fd;
681:   ovascii->tab = vascii->tab;

683:   vascii->sviewer = *outviewer;

685:   (*outviewer)->format     = viewer->format;
686:   (*outviewer)->iformat    = viewer->iformat;

688:   PetscObjectGetName((PetscObject)viewer,&name);
689:   PetscObjectSetName((PetscObject)(*outviewer),name);

691:   MPI_Comm_rank(viewer->comm,&rank);
692:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
693:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
694:   /* following might not be correct??? */
695:   if (rank) {
696:     (*outviewer)->ops->flush = 0;
697:   } else {
698:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
699:   }
700:   return(0);
701: }

705: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
706: {
707:   PetscErrorCode    ierr;
708:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
709:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

712:   if (!ascii->sviewer) {
713:     SETERRQ(PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
714:   }
715:   if (ascii->sviewer != *outviewer) {
716:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
717:   }

719:   ascii->sviewer             = 0;
720:   vascii->fd                 = stdout;
721:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
722:   PetscViewerDestroy(*outviewer);
723:   PetscViewerFlush(viewer);
724:   return(0);
725: }

730: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
731: {
732:   PetscViewer_ASCII *vascii;
733:   PetscErrorCode    ierr;

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

739:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
740:   viewer->ops->flush            = PetscViewerFlush_ASCII;
741:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
742:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
743:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
744:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;

746:   /* defaults to stdout unless set with PetscViewerFileSetName() */
747:   vascii->fd             = stdout;
748:   vascii->mode           = FILE_MODE_WRITE;
749:   vascii->bviewer        = 0;
750:   vascii->sviewer        = 0;
751:   viewer->format         = PETSC_VIEWER_ASCII_DEFAULT;
752:   viewer->iformat        = 0;
753:   vascii->tab            = 0;
754:   vascii->tab_store      = 0;
755:   vascii->filename       = 0;

757:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
758:                                      PetscViewerFileSetName_ASCII);
759:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
760:                                      PetscViewerFileGetName_ASCII);
761:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
762:                                      PetscViewerFileGetMode_ASCII);
763:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
764:                                      PetscViewerFileSetMode_ASCII);

766:   return(0);
767: }


773: /*@C
774:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
775:     several processors.  Output of the first processor is followed by that of the 
776:     second, etc.

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

780:     Input Parameters:
781: +   viewer - the ASCII PetscViewer
782: -   format - the usual printf() format string 

784:     Level: intermediate

786:     Fortran Note:
787:       Can only print a single character* string

789: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
790:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
791:           PetscViewerASCIIPrintf()

793: @*/
794: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
795: {
796:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
797:   PetscErrorCode    ierr;
798:   PetscMPIInt       rank;
799:   PetscInt          tab = vascii->tab;
800:   MPI_Comm          comm;
801:   FILE              *fp;
802:   PetscTruth        iascii;

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

810:   comm = viewer->comm;
811:   fp   = vascii->fd;
812:   MPI_Comm_rank(comm,&rank);
813:   if (vascii->bviewer) {MPI_Comm_rank(vascii->bviewer->comm,&rank);}
814: 

816:   /* First processor prints immediately to fp */
817:   if (!rank) {
818:     va_list Argp;

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

822:     va_start(Argp,format);
823:     PetscVFPrintf(fp,format,Argp);
824:     fflush(fp);
825:     queuefile = fp;
826:     if (petsc_history) {
827:       PetscVFPrintf(petsc_history,format,Argp);
828:       fflush(petsc_history);
829:     }
830:     va_end(Argp);
831:   } else { /* other processors add to local queue */
832:     char        *string;
833:     va_list     Argp;
834:     PrintfQueue next;

836:     PetscNew(struct _PrintfQueue,&next);
837:     if (queue) {queue->next = next; queue = next;}
838:     else       {queuebase   = queue = next;}
839:     queuelength++;
840:     string = next->string;
841:     PetscMemzero(string,QUEUESTRINGSIZE);
842:     tab *= 2;
843:     while (tab--) {*string++ = ' ';}
844:     va_start(Argp,format);
845:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*vascii->tab,format,Argp);
846:     va_end(Argp);
847:   }
848:   return(0);
849: }


854: /*@C
855:    PetscViewerASCIIMonitorCreate - Opens an ASCII file as a monitor object, suitable for the default KSP, SNES and TS monitors

857:    Collective on MPI_Comm

859:    Input Parameters:
860: +  comm - the communicator
861: .  name - the file name
862: -  tabs - how far in the text should be tabbed

864:    Output Parameter:
865: .  lab - the context to be used with KSP/SNES/TSMonitorSet()

867:    Level: advanced

869:    Notes:
870:    This can be destroyed with PetscViewerASCIIMonitorDestroy().

872:    See PetscViewerASCIIOpen()

874: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorDestroy()

876: @*/
877: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
878: {

882:   PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
883:   PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
884:   (*ctx)->tabs = tabs;
885:   return(0);
886: }

890: /*@C
891:    PetscViewerASCIIMonitorDestroys - removes a monitor context.

893:    Collective on PetscViewerASCIIMonitor

895:    Input Parameters:
896: .   ctx - the monitor context created with PetscViewerASCIIMonitorCreate()

898:    Level: advanced

900:    Notes:
901:      This is rarely called by users, it is usually called when the KSP, SNES or TS object is destroyed

903: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate()

905: @*/
906: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
907: {

911:   PetscViewerDestroy(ctx->viewer);
912:   PetscFree(ctx);
913:   return(0);
914: }

918: /*@C
919:     PetscViewerASCIIMonitorPrintf - Prints to the viewer associated with this monitor context

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

923:     Input Parameters:
924: +    ctx - the context obtained with PetscViewerASCIIMonitorCreate()
925: -    format - the usual printf() format string 

927:     Level: developer

929:     Developer Notes: This code is virtually identical to PetscViewerASCIIPrintf(), however the code
930:       could not simply be called from here due to the var args.

932: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
933:           PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()


936: @*/
937: PetscErrorCode  PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
938: {
939:   PetscViewer       viewer = ctx->viewer;
940:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
941:   PetscMPIInt       rank;
942:   PetscInt          tab;
943:   PetscErrorCode    ierr;
944:   FILE              *fd = ascii->fd;
945:   PetscTruth        iascii;

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

953:   MPI_Comm_rank(viewer->comm,&rank);
954:   if (ascii->bviewer) {MPI_Comm_rank(ascii->bviewer->comm,&rank);}
955:   if (!rank) {
956:     va_list Argp;
957:     if (ascii->bviewer) {
958:       queuefile = fd;
959:     }

961:     tab = ascii->tab + ctx->tabs;
962:     while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}

964:     va_start(Argp,format);
965:     PetscVFPrintf(fd,format,Argp);
966:     fflush(fd);
967:     if (petsc_history) {
968:       tab = ascii->tab + ctx->tabs;
969:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
970:       PetscVFPrintf(petsc_history,format,Argp);
971:       fflush(petsc_history);
972:     }
973:     va_end(Argp);
974:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
975:     va_list     Argp;
976:     char        *string;

978:     PrintfQueue next;
979:     PetscNew(struct _PrintfQueue,&next);
980:     if (queue) {queue->next = next; queue = next;}
981:     else       {queuebase   = queue = next;}
982:     queuelength++;
983:     string = next->string;
984:     PetscMemzero(string,QUEUESTRINGSIZE);
985:     tab = 2*(ascii->tab + ctx->tabs);
986:     while (tab--) {*string++ = ' ';}
987:     va_start(Argp,format);
988:     PetscVSNPrintf(string,QUEUESTRINGSIZE-2*ascii->tab,format,Argp);
989:     va_end(Argp);
990:   }
991:   return(0);
992: }