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: #define QUEUESTRINGSIZE 8192

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

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

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

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

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

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

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

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

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

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

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

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

137:     Not Collective

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

142:     Level: intermediate

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

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

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

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

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

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

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

178:     Not Collective

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

183:     Level: intermediate

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

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

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

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

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

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

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

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

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

223:     Level: developer

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

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

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

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

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

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

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

261:     Level: developer

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

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

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

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

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

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

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

299:     Level: developer

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

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

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

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

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

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

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

338:     Level: developer

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

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

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

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

370: /* ----------------------------------------------------------------------- */

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

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

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

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

386:     Level: developer

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

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

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

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

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

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

427:     va_start(Argp,format);
428:     PetscVFPrintf(fd,format,Argp);
429:     err = fflush(fd);
430:     if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
431:     if (petsc_history) {
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:       (*PetscVFPrintf)(petsc_history,format,Argp);
846:       err = fflush(petsc_history);
847:       if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on file");
848:     }
849:     va_end(Argp);
850:   } else { /* other processors add to local queue */
851:     char        *string;
852:     va_list     Argp;
853:     int         fullLength;
854:     PrintfQueue next;

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


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

879:    Collective on MPI_Comm

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

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

889:    Level: advanced

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

894:    See PetscViewerASCIIOpen()

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

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

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

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

915:    Collective on PetscViewerASCIIMonitor

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

920:    Level: advanced

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

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

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

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

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

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

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

949:     Level: developer

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

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


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

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

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

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

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

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