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

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

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

466:     Collective on PetscViewer

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

472:     Level: advanced

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

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

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

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

497:     Not Collective

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

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

505:     Level: advanced

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

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

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

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

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


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

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

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


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

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

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

635:   vascii->sviewer = *outviewer;

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

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

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

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

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

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

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

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

698:   vascii->sviewer = *outviewer;

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

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

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

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

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

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

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

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

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

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

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

781:   return(0);
782: }


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

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

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

799:     Level: intermediate

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

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

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

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

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

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

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

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

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


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

878:    Collective on MPI_Comm

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

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

888:    Level: advanced

890:    Notes:
891:    This can be destroyed with PetscViewerASCIIMonitorDestroy().

893:    See PetscViewerASCIIOpen()

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

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

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

911: /*@C
912:    PetscViewerASCIIMonitorDestroys - removes a monitor context.

914:    Collective on PetscViewerASCIIMonitor

916:    Input Parameters:
917: .   ctx - the monitor context created with PetscViewerASCIIMonitorCreate()

919:    Level: advanced

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

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

926: @*/
927: PetscErrorCode PetscViewerASCIIMonitorDestroy(PetscViewerASCIIMonitor ctx)
928: {

932:   PetscViewerDestroy(ctx->viewer);
933:   PetscFree(ctx);
934:   return(0);
935: }

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

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

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

948:     Level: developer

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

953: .seealso: KSPMonitorSet(), SNESMonitorSet(), TSMonitorSet(), KSPMonitorDefault(), PetscViewerASCIIMonitor, PetscViewerASCIIMonitorCreate(),
954:           PetscPrintf(), PetscFPrintf(), PetscViewerASCIIPrintf()


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

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

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

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

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

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