Actual source code: filev.c

  1: #define PETSC_DLL

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

  6: #define QUEUESTRINGSIZE 8192

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

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

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

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

 75: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 76: {
 77:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 78:   PetscErrorCode    ierr;
 80:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 81:   return(0);
 82: }

 86: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
 87: {
 88:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 89:   PetscErrorCode    ierr;
 91:   PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
 92:   return(0);
 93: }

 97: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
 98: {
 99:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
100:   int               err;

103:   err = fflush(vascii->fd);
104:   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
105:   return(0);
106: }

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

118:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
119:   if (!rank) {
120:     err = fflush(vascii->fd);
121:     if (err) SETERRQ(PETSC_ERR_SYS,"fflush() call failed");
122:   }

124:   /*
125:      Also flush anything printed with PetscViewerASCIISynchronizedPrintf()
126:   */
127:   PetscSynchronizedFlush(((PetscObject)viewer)->comm);
128:   return(0);
129: }

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

136:     Not Collective

138: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
139: -   fd - file pointer

141:     Level: intermediate

143:     Fortran Note:
144:     This routine is not supported in Fortran.

146:   Concepts: PetscViewer^file pointer
147:   Concepts: file pointer^getting from PetscViewer

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

157:   *fd = vascii->fd;
158:   return(0);
159: }

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

169:   *mode = vascii->mode;
170:   return(0);
171: }

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

177:     Not Collective

179: +   viewer - viewer context, obtained from PetscViewerCreate()
180: -   mode   - The file mode

182:     Level: intermediate

184:     Fortran Note:
185:     This routine is not supported in Fortran.

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

189: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
190: @*/

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

200:   vascii->mode = mode;
201:   return(0);
202: }

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

213: /*@
214:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

218:     Input Parameters:
219: +    viewer - optained with PetscViewerASCIIOpen()
220: -    tabs - number of tabs

222:     Level: developer

224:     Fortran Note:
225:     This routine is not supported in Fortran.

227:   Concepts: PetscViewerASCII^formating
228:   Concepts: tab^setting

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

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

251: /*@
252:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
253:      lines are tabbed.

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

257:     Input Parameters:
258: .    viewer - optained with PetscViewerASCIIOpen()

260:     Level: developer

262:     Fortran Note:
263:     This routine is not supported in Fortran.

265:   Concepts: PetscViewerASCII^formating
266:   Concepts: tab^setting

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

280:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
281:   if (iascii) {
282:     ascii->tab++;
283:   }
284:   return(0);
285: }

289: /*@
290:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
291:      lines are tabbed.

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

295:     Input Parameters:
296: .    viewer - optained with PetscViewerASCIIOpen()

298:     Level: developer

300:     Fortran Note:
301:     This routine is not supported in Fortran.

303:   Concepts: PetscViewerASCII^formating
304:   Concepts: tab^setting

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

318:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
319:   if (iascii) {
320:     if (ascii->tab <= 0) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
321:     ascii->tab--;
322:   }
323:   return(0);
324: }

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

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

333:     Input Parameters:
334: +    viewer - optained with PetscViewerASCIIOpen()
335: -    flg - PETSC_YES or PETSC_NO

337:     Level: developer

339:     Fortran Note:
340:     This routine is not supported in Fortran.

342:   Concepts: PetscViewerASCII^formating
343:   Concepts: tab^setting

345: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
346:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
347:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
348: @*/
349: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscTruth flg)
350: {
351:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
352:   PetscTruth        iascii;
353:   PetscErrorCode    ierr;

357:   PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
358:   if (iascii) {
359:     if (flg) {
360:       ascii->tab       = ascii->tab_store;
361:     } else {
362:       ascii->tab_store = ascii->tab;
363:       ascii->tab       = 0;
364:     }
365:   }
366:   return(0);
367: }

369: /* ----------------------------------------------------------------------- */

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

375: /*@C
376:     PetscViewerASCIIPrintf - Prints to a file, only from the first
377:     processor in the PetscViewer

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

381:     Input Parameters:
382: +    viewer - optained with PetscViewerASCIIOpen()
383: -    format - the usual printf() format string 

385:     Level: developer

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

391:   Concepts: PetscViewerASCII^printing
392:   Concepts: printing^to file
393:   Concepts: printf

395: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
396:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
397:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
398: @*/
399: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
400: {
401:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
402:   PetscMPIInt       rank;
403:   PetscInt          tab;
404:   PetscErrorCode    ierr;
405:   FILE              *fd = ascii->fd;
406:   PetscTruth        iascii;
407:   int               err;

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

415:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
416:   if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
417:   if (!rank) {
418:     va_list Argp;
419:     if (ascii->bviewer) {
420:       queuefile = fd;
421:     }

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

426:     va_start(Argp,format);
427:     PetscVFPrintf(fd,format,Argp);
428:     err = fflush(fd);
429:     if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
430:     if (petsc_history) {
431:       va_start(Argp,format);
432:       tab = ascii->tab;
433:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
434:       (*PetscVFPrintf)(petsc_history,format,Argp);
435:       err = fflush(petsc_history);
436:       if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
437:     }
438:     va_end(Argp);
439:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
440:     va_list     Argp;
441:     int         fullLength;
442:     char        *string;

444:     PrintfQueue next;
445:     PetscNew(struct _PrintfQueue,&next);
446:     if (queue) {queue->next = next; queue = next;}
447:     else       {queuebase   = queue = next;}
448:     queuelength++;
449:     next->size = QUEUESTRINGSIZE;
450:     PetscMalloc(next->size*sizeof(char), &next->string);
451:     PetscMemzero(next->string,next->size);
452:     string = next->string;
453:     tab = 2*ascii->tab;
454:     while (tab--) {*string++ = ' ';}
455:     va_start(Argp,format);
456:     PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
457:     va_end(Argp);
458:   }
459:   return(0);
460: }

464: /*@C
465:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

467:     Collective on PetscViewer

469:   Input Parameters:
470: +  viewer - the PetscViewer; either ASCII or binary
471: -  name - the name of the file it should use

473:     Level: advanced

475: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
476:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

478: @*/
479: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
480: {
481:   PetscErrorCode ierr,(*f)(PetscViewer,const char[]);

486:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileSetName_C",(void (**)(void))&f);
487:   if (f) {
488:     (*f)(viewer,name);
489:   }
490:   return(0);
491: }

495: /*@C
496:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

498:     Not Collective

500:   Input Parameter:
501: .  viewer - the PetscViewer; either ASCII or binary

503:   Output Parameter:
504: .  name - the name of the file it is using

506:     Level: advanced

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

510: @*/
511: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,char **name)
512: {
513:   PetscErrorCode ierr,(*f)(PetscViewer,char **);

517:   PetscObjectQueryFunction((PetscObject)viewer,"PetscViewerFileGetName_C",(void (**)(void))&f);
518:   if (f) {
519:     (*f)(viewer,name);
520:   }
521:   return(0);
522: }

527: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,char **name)
528: {
529:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

532:   *name = vascii->filename;
533:   return(0);
534: }


541: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
542: {
543:   PetscErrorCode    ierr;
544:   size_t            len;
545:   char              fname[PETSC_MAX_PATH_LEN],*gz;
546:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
547:   PetscTruth        isstderr,isstdout;
548:   PetscMPIInt       rank;

551:   if (!name) return(0);
552:   PetscStrfree(vascii->filename);
553:   PetscStrallocpy(name,&vascii->filename);

555:   /* Is this file to be compressed */
556:   vascii->storecompressed = PETSC_FALSE;
557:   PetscStrstr(vascii->filename,".gz",&gz);
558:   if (gz) {
559:     PetscStrlen(gz,&len);
560:     if (len == 3) {
561:       *gz = 0;
562:       vascii->storecompressed = PETSC_TRUE;
563:     }
564:   }
565:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
566:   if (!rank) {
567:     PetscStrcmp(name,"stderr",&isstderr);
568:     PetscStrcmp(name,"stdout",&isstdout);
569:     /* empty filename means stdout */
570:     if (name[0] == 0)  isstdout = PETSC_TRUE;
571:     if (isstderr)      vascii->fd = PETSC_STDERR;
572:     else if (isstdout) vascii->fd = PETSC_STDOUT;
573:     else {


576:       PetscFixFilename(name,fname);
577:       switch(vascii->mode) {
578:       case FILE_MODE_READ:
579:         vascii->fd = fopen(fname,"r");
580:         break;
581:       case FILE_MODE_WRITE:
582:         vascii->fd = fopen(fname,"w");
583:         break;
584:       case FILE_MODE_APPEND:
585:         vascii->fd = fopen(fname,"a");
586:         break;
587:       case FILE_MODE_UPDATE:
588:         vascii->fd = fopen(fname,"r+");
589:         if (!vascii->fd) {
590:           vascii->fd = fopen(fname,"w+");
591:         }
592:         break;
593:       case FILE_MODE_APPEND_UPDATE:
594:         /* I really want a file which is opened at the end for updating,
595:            not a+, which opens at the beginning, but makes writes at the end.
596:         */
597:         vascii->fd = fopen(fname,"r+");
598:         if (!vascii->fd) {
599:           vascii->fd = fopen(fname,"w+");
600:         } else {
601:           fseek(vascii->fd, 0, SEEK_END);
602:         }
603:         break;
604:       default:
605:         SETERRQ1(PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
606:       }
607:       if (!vascii->fd) SETERRQ1(PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
608:     }
609:   }
610: #if defined(PETSC_USE_LOG)
611:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
612: #endif
613:   return(0);
614: }

619: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
620: {
621:   PetscMPIInt       rank;
622:   PetscErrorCode    ierr;
623:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
624:   const char        *name;

627:   if (vascii->sviewer) {
628:     SETERRQ(PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
629:   }
630:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
631:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
632:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
633:   ovascii->fd  = vascii->fd;
634:   ovascii->tab = vascii->tab;

636:   vascii->sviewer = *outviewer;

638:   (*outviewer)->format     = viewer->format;
639:   (*outviewer)->iformat    = viewer->iformat;

641:   PetscObjectGetName((PetscObject)viewer,&name);
642:   PetscObjectSetName((PetscObject)(*outviewer),name);

644:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
645:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
646:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
647:   if (rank) {
648:     (*outviewer)->ops->flush = 0;
649:   } else {
650:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
651:   }
652:   return(0);
653: }

657: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
658: {
659:   PetscErrorCode    ierr;
660:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
661:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

664:   if (!ascii->sviewer) {
665:     SETERRQ(PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
666:   }
667:   if (ascii->sviewer != *outviewer) {
668:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");
669:   }

671:   ascii->sviewer             = 0;
672:   vascii->fd                 = PETSC_STDOUT;
673:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
674:   PetscViewerDestroy(*outviewer);
675:   PetscViewerFlush(viewer);
676:   return(0);
677: }

681: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
682: {
683:   PetscMPIInt       rank;
684:   PetscErrorCode    ierr;
685:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
686:   const char        *name;

689:   if (vascii->sviewer) {
690:     SETERRQ(PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
691:   }
692:   /* PetscViewerCreate(PETSC_COMM_SELF,outviewer); */
693:   PetscViewerCreate(subcomm,outviewer);
694:   PetscViewerSetType(*outviewer,PETSC_VIEWER_ASCII);
695:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
696:   ovascii->fd  = vascii->fd;
697:   ovascii->tab = vascii->tab;

699:   vascii->sviewer = *outviewer;

701:   (*outviewer)->format     = viewer->format;
702:   (*outviewer)->iformat    = viewer->iformat;

704:   PetscObjectGetName((PetscObject)viewer,&name);
705:   PetscObjectSetName((PetscObject)(*outviewer),name);

707:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
708:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
709:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
710:   /* following might not be correct??? */
711:   if (rank) {
712:     (*outviewer)->ops->flush = 0;
713:   } else {
714:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
715:   }
716:   return(0);
717: }

721: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
722: {
723:   PetscErrorCode    ierr;
724:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
725:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

728:   if (!ascii->sviewer) {
729:     SETERRQ(PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
730:   }
731:   if (ascii->sviewer != *outviewer) {
732:     SETERRQ(PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");
733:   }

735:   ascii->sviewer             = 0;
736:   vascii->fd                 = PETSC_STDOUT;
737:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
738:   PetscViewerDestroy(*outviewer);
739:   PetscViewerFlush(viewer);
740:   return(0);
741: }

746: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
747: {
748:   PetscViewer_ASCII *vascii;
749:   PetscErrorCode    ierr;

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

755:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
756:   viewer->ops->flush            = PetscViewerFlush_ASCII;
757:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
758:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
759:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
760:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;

762:   /* defaults to stdout unless set with PetscViewerFileSetName() */
763:   vascii->fd             = PETSC_STDOUT;
764:   vascii->mode           = FILE_MODE_WRITE;
765:   vascii->bviewer        = 0;
766:   vascii->sviewer        = 0;
767:   viewer->format         = PETSC_VIEWER_DEFAULT;
768:   viewer->iformat        = 0;
769:   vascii->tab            = 0;
770:   vascii->tab_store      = 0;
771:   vascii->filename       = 0;

773:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
774:                                      PetscViewerFileSetName_ASCII);
775:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
776:                                      PetscViewerFileGetName_ASCII);
777:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
778:                                      PetscViewerFileGetMode_ASCII);
779:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
780:                                      PetscViewerFileSetMode_ASCII);

782:   return(0);
783: }


789: /*@C
790:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
791:     several processors.  Output of the first processor is followed by that of the 
792:     second, etc.

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

796:     Input Parameters:
797: +   viewer - the ASCII PetscViewer
798: -   format - the usual printf() format string 

800:     Level: intermediate

802:     Fortran Note:
803:       Can only print a single character* string

805: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
806:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
807:           PetscViewerASCIIPrintf()

809: @*/
810: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
811: {
812:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
813:   PetscErrorCode    ierr;
814:   PetscMPIInt       rank;
815:   PetscInt          tab = vascii->tab;
816:   MPI_Comm          comm;
817:   FILE              *fp;
818:   PetscTruth        iascii;
819:   int               err;

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

827:   comm = ((PetscObject)viewer)->comm;
828:   fp   = vascii->fd;
829:   MPI_Comm_rank(comm,&rank);
830:   if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
831: 

833:   /* First processor prints immediately to fp */
834:   if (!rank) {
835:     va_list Argp;

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

839:     va_start(Argp,format);
840:     (*PetscVFPrintf)(fp,format,Argp);
841:     err = fflush(fp);
842:     if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
843:     queuefile = fp;
844:     if (petsc_history) {
845:       va_start(Argp,format);
846:       (*PetscVFPrintf)(petsc_history,format,Argp);
847:       err = fflush(petsc_history);
848:       if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
849:     }
850:     va_end(Argp);
851:   } else { /* other processors add to local queue */
852:     char        *string;
853:     va_list     Argp;
854:     int         fullLength;
855:     PrintfQueue next;

857:     PetscNew(struct _PrintfQueue,&next);
858:     if (queue) {queue->next = next; queue = next;}
859:     else       {queuebase   = queue = next;}
860:     queuelength++;
861:     next->size = QUEUESTRINGSIZE;
862:     PetscMalloc(next->size*sizeof(char), &next->string);
863:     PetscMemzero(next->string,next->size);
864:     string = next->string;
865:     tab *= 2;
866:     while (tab--) {*string++ = ' ';}
867:     va_start(Argp,format);
868:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
869:     va_end(Argp);
870:   }
871:   return(0);
872: }


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

880:    Collective on MPI_Comm

882:    Input Parameters:
883: +  comm - the communicator
884: .  name - the file name
885: -  tabs - how far in the text should be tabbed

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

890:    Level: advanced

892:    Notes:
893:    This can be destroyed with PetscViewerASCIIMonitorDestroy().

895:    See PetscViewerASCIIOpen()

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

899: @*/
900: PetscErrorCode PetscViewerASCIIMonitorCreate(MPI_Comm comm,const char *filename,PetscInt tabs,PetscViewerASCIIMonitor* ctx)
901: {

905:   PetscNew(struct _p_PetscViewerASCIIMonitor,ctx);
906:   PetscViewerASCIIOpen(comm,filename,&(*ctx)->viewer);
907:   (*ctx)->tabs = tabs;
908:   return(0);
909: }

913: /*@C
914:    PetscViewerASCIIMonitorDestroys - removes a monitor context.

916:    Collective on PetscViewerASCIIMonitor

918:    Input Parameters:
919: .   ctx - the monitor context created with PetscViewerASCIIMonitorCreate()

921:    Level: advanced

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

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

928: @*/
929: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
930: {

934:   PetscViewerDestroy(ctx->viewer);
935:   PetscFree(ctx);
936:   return(0);
937: }

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

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

946:     Input Parameters:
947: +    ctx - the context obtained with PetscViewerASCIIMonitorCreate()
948: -    format - the usual printf() format string 

950:     Level: developer

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

955: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
956:           PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()


959: @*/
960: PetscErrorCode  PetscViewerASCIIMonitorPrintf(PetscViewerASCIIMonitor ctx,const char format[],...)
961: {
962:   PetscViewer       viewer = ctx->viewer;
963:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
964:   PetscMPIInt       rank;
965:   PetscInt          tab;
966:   PetscErrorCode    ierr;
967:   FILE              *fd = ascii->fd;
968:   PetscTruth        iascii;
969:   int               err;

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

977:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
978:   if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
979:   if (!rank) {
980:     va_list Argp;
981:     if (ascii->bviewer) {
982:       queuefile = fd;
983:     }

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

988:     va_start(Argp,format);
989:     (*PetscVFPrintf)(fd,format,Argp);
990:     err = fflush(fd);
991:     if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
992:     if (petsc_history) {
993:       va_start(Argp,format);
994:       tab = ascii->tab + ctx->tabs;
995:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
996:       (*PetscVFPrintf)(petsc_history,format,Argp);
997:       err = fflush(petsc_history);
998:       if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
999:     }
1000:     va_end(Argp);
1001:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
1002:     va_list     Argp;
1003:     int         fullLength;
1004:     char        *string;
1005:     PrintfQueue next;

1007:     PetscNew(struct _PrintfQueue,&next);
1008:     if (queue) {queue->next = next; queue = next;}
1009:     else       {queuebase   = queue = next;}
1010:     queuelength++;
1011:     next->size = QUEUESTRINGSIZE;
1012:     PetscMalloc(next->size*sizeof(char), &next->string);
1013:     PetscMemzero(next->string,next->size);
1014:     string = next->string;
1015:     tab = 2*(ascii->tab + ctx->tabs);
1016:     while (tab--) {*string++ = ' ';}
1017:     va_start(Argp,format);
1018:     PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
1019:     va_end(Argp);
1020:   }
1021:   return(0);
1022: }