Actual source code: filev.c

petsc-3.3-p7 2013-05-11
  2: #include <../src/sys/viewer/impls/ascii/asciiimpl.h>  /*I     "petscsys.h"   I*/
  3: #include <stdarg.h>

  5: #define QUEUESTRINGSIZE 8192

  9: static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
 10: {
 11:   PetscErrorCode    ierr;
 12:   PetscMPIInt       rank;
 13:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 14:   int               err;

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

 43: /* ----------------------------------------------------------------------*/
 46: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
 47: {
 48:   PetscErrorCode    ierr;
 49:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 50:   PetscViewerLink   *vlink;
 51:   PetscBool         flg;

 54:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"ASCII PetscViewer destroyed before restoring singleton or subcomm PetscViewer");
 55:   PetscViewerFileClose_ASCII(viewer);
 56:   PetscFree(vascii);

 58:   /* remove the viewer from the list in the MPI Communicator */
 59:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
 60:     MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
 61:   }

 63:   MPI_Attr_get(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
 64:   if (flg) {
 65:     if (vlink && vlink->viewer == viewer) {
 66:       MPI_Attr_put(((PetscObject)viewer)->comm,Petsc_Viewer_keyval,vlink->next);
 67:       PetscFree(vlink);
 68:     } else {
 69:       while (vlink && vlink->next) {
 70:         if (vlink->next->viewer == viewer) {
 71:           PetscViewerLink *nv = vlink->next;
 72:           vlink->next = vlink->next->next;
 73:           PetscFree(nv);
 74:         }
 75:         vlink = vlink->next;
 76:       }
 77:     }
 78:   }
 79:   return(0);
 80: }

 84: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 85: {
 86:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 87:   PetscErrorCode    ierr;
 89:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 90:   return(0);
 91: }

 95: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
 96: {
 97:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
 98:   PetscErrorCode    ierr;
100:   PetscViewerRestoreSubcomm(vascii->bviewer,((PetscObject)viewer)->comm,&viewer);
101:   return(0);
102: }

106: PetscErrorCode PetscViewerFlush_ASCII_Singleton_0(PetscViewer viewer)
107: {
108:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
109:   int               err;

112:   err = fflush(vascii->fd);
113:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
114:   return(0);
115: }

119: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
120: {
121:   PetscMPIInt       rank;
122:   PetscErrorCode    ierr;
123:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
124:   int               err;

127:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
128:   /* fflush() fails on OSX for read-only descriptors */
129:   if (!rank && (vascii->mode != FILE_MODE_READ)) {
130:     err = fflush(vascii->fd);
131:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
132:   }

134:   if (vascii->allowsynchronized) {
135:     /* Also flush anything printed with PetscViewerASCIISynchronizedPrintf()  */
136:     PetscSynchronizedFlush(((PetscObject)viewer)->comm);
137:   }
138:   return(0);
139: }

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

146:     Not Collective

148: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
149: -   fd - file pointer

151:     Level: intermediate

153:     Fortran Note:
154:     This routine is not supported in Fortran.

156:   Concepts: PetscViewer^file pointer
157:   Concepts: file pointer^getting from PetscViewer

159: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
160:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
161: @*/
162: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
163: {
164:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

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

171: EXTERN_C_BEGIN
174: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
175: {
176:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

179:   *mode = vascii->mode;
180:   return(0);
181: }
182: EXTERN_C_END

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

187:     Not Collective

189: +   viewer - viewer context, obtained from PetscViewerCreate()
190: -   mode   - The file mode

192:     Level: intermediate

194:     Fortran Note:
195:     This routine is not supported in Fortran.

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

199: .seealso: PetscViewerASCIIOpen(), PetscViewerBinaryOpen()
200: @*/

202: EXTERN_C_BEGIN
205: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
206: {
207:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;

210:   vascii->mode = mode;
211:   return(0);
212: }
213: EXTERN_C_END

215: /*
216:    If petsc_history is on, then all Petsc*Printf() results are saved
217:    if the appropriate (usually .petschistory) file.
218: */
219: extern FILE *petsc_history;

223: /*@
224:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

228:     Input Parameters:
229: +    viewer - optained with PetscViewerASCIIOpen()
230: -    tabs - number of tabs

232:     Level: developer

234:     Fortran Note:
235:     This routine is not supported in Fortran.

237:   Concepts: PetscViewerASCII^formating
238:   Concepts: tab^setting

240: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
241:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
242:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
243: @*/
244: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
245: {
246:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
247:   PetscBool         iascii;
248:   PetscErrorCode    ierr;

252:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253:   if (iascii) {
254:     ascii->tab = tabs;
255:   }
256:   return(0);
257: }

261: /*@
262:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

264:     Not Collective, meaningful on first processor only.

266:     Input Parameters:
267: .    viewer - optained with PetscViewerASCIIOpen()
268:     Output Parameters:
269: .    tabs - number of tabs

271:     Level: developer

273:     Fortran Note:
274:     This routine is not supported in Fortran.

276:   Concepts: PetscViewerASCII^formating
277:   Concepts: tab^retrieval

279: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
280:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
281:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
282: @*/
283: PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
284: {
285:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
286:   PetscBool         iascii;
287:   PetscErrorCode    ierr;

291:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
292:   if (iascii && tabs) {
293:     *tabs = ascii->tab;
294:   }
295:   return(0);
296: }

300: /*@
301:     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing

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

305:     Input Parameters:
306: +    viewer - optained with PetscViewerASCIIOpen()
307: -    tabs - number of tabs

309:     Level: developer

311:     Fortran Note:
312:     This routine is not supported in Fortran.

314:   Concepts: PetscViewerASCII^formating
315:   Concepts: tab^setting

317: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
318:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
319:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
320: @*/
321: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
322: {
323:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
324:   PetscBool         iascii;
325:   PetscErrorCode    ierr;

329:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
330:   if (iascii) {
331:     ascii->tab += tabs;
332:   }
333:   return(0);
334: }

338: /*@
339:     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing

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

343:     Input Parameters:
344: +    viewer - optained with PetscViewerASCIIOpen()
345: -    tabs - number of tabs

347:     Level: developer

349:     Fortran Note:
350:     This routine is not supported in Fortran.

352:   Concepts: PetscViewerASCII^formating
353:   Concepts: tab^setting

355: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
356:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
357:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
358: @*/
359: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
360: {
361:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
362:   PetscBool         iascii;
363:   PetscErrorCode    ierr;

367:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
368:   if (iascii) {
369:     ascii->tab -= tabs;
370:   }
371:   return(0);
372: }

376: /*@C
377:     PetscViewerASCIISynchronizedAllow - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

379:     Collective on PetscViewer

381:     Input Parameters:
382: +    viewer - optained with PetscViewerASCIIOpen()
383: -    allow - PETSC_TRUE to allow the synchronized printing

385:     Level: intermediate

387:   Concepts: PetscViewerASCII^formating
388:   Concepts: tab^setting

390: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
391:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
392:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
393: @*/
394: PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
395: {
396:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
397:   PetscBool         iascii;
398:   PetscErrorCode    ierr;

402:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
403:   if (iascii) {
404:     ascii->allowsynchronized = allow;
405:   }
406:   return(0);
407: }

411: /*@
412:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
413:      lines are tabbed.

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

417:     Input Parameters:
418: .    viewer - optained with PetscViewerASCIIOpen()

420:     Level: developer

422:     Fortran Note:
423:     This routine is not supported in Fortran.

425:   Concepts: PetscViewerASCII^formating
426:   Concepts: tab^setting

428: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
429:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
430:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
431: @*/
432: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
433: {
434:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
435:   PetscBool         iascii;
436:   PetscErrorCode    ierr;

440:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
441:   if (iascii) {
442:     ascii->tab++;
443:   }
444:   return(0);
445: }

449: /*@
450:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
451:      lines are tabbed.

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

455:     Input Parameters:
456: .    viewer - optained with PetscViewerASCIIOpen()

458:     Level: developer

460:     Fortran Note:
461:     This routine is not supported in Fortran.

463:   Concepts: PetscViewerASCII^formating
464:   Concepts: tab^setting

466: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
467:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
468:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469: @*/
470: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
471: {
472:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473:   PetscErrorCode    ierr;
474:   PetscBool         iascii;

478:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
479:   if (iascii) {
480:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
481:     ascii->tab--;
482:   }
483:   return(0);
484: }

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

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

493:     Input Parameters:
494: +    viewer - optained with PetscViewerASCIIOpen()
495: -    flg - PETSC_TRUE or PETSC_FALSE

497:     Level: developer

499:     Fortran Note:
500:     This routine is not supported in Fortran.

502:   Concepts: PetscViewerASCII^formating
503:   Concepts: tab^setting

505: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
506:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
507:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
508: @*/
509: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool  flg)
510: {
511:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
512:   PetscBool         iascii;
513:   PetscErrorCode    ierr;

517:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
518:   if (iascii) {
519:     if (flg) {
520:       ascii->tab       = ascii->tab_store;
521:     } else {
522:       ascii->tab_store = ascii->tab;
523:       ascii->tab       = 0;
524:     }
525:   }
526:   return(0);
527: }

529: /* ----------------------------------------------------------------------- */

531: #include <../src/sys/fileio/mprint.h> /* defines the queue datastructures and variables */

535: /*@C
536:     PetscViewerASCIIPrintf - Prints to a file, only from the first
537:     processor in the PetscViewer

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

541:     Input Parameters:
542: +    viewer - optained with PetscViewerASCIIOpen()
543: -    format - the usual printf() format string 

545:     Level: developer

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

551:   Concepts: PetscViewerASCII^printing
552:   Concepts: printing^to file
553:   Concepts: printf

555: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
556:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
557:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
558: @*/
559: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
560: {
561:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
562:   PetscMPIInt       rank;
563:   PetscInt          tab;
564:   PetscErrorCode    ierr;
565:   FILE              *fd = ascii->fd;
566:   PetscBool         iascii;
567:   int               err;

572:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
573:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

575:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
576:   if (!rank) {
577:     va_list Argp;
578:     if (ascii->bviewer) {
579:       petsc_printfqueuefile = fd;
580:     }

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

585:     va_start(Argp,format);
586:     (*PetscVFPrintf)(fd,format,Argp);
587:     err = fflush(fd);
588:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
589:     if (petsc_history) {
590:       va_start(Argp,format);
591:       tab = ascii->tab;
592:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
593:       (*PetscVFPrintf)(petsc_history,format,Argp);
594:       err = fflush(petsc_history);
595:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
596:     }
597:     va_end(Argp);
598:   }
599:   return(0);
600: }

604: /*@C
605:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

607:     Collective on PetscViewer

609:   Input Parameters:
610: +  viewer - the PetscViewer; either ASCII or binary
611: -  name - the name of the file it should use

613:     Level: advanced

615: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
616:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

618: @*/
619: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
620: {

626:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
627:   return(0);
628: }

632: /*@C
633:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

635:     Not Collective

637:   Input Parameter:
638: .  viewer - the PetscViewer; either ASCII or binary

640:   Output Parameter:
641: .  name - the name of the file it is using

643:     Level: advanced

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

647: @*/
648: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
649: {

654:   PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
655:   return(0);
656: }

658: EXTERN_C_BEGIN
661: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
662: {
663:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

666:   *name = vascii->filename;
667:   return(0);
668: }
669: EXTERN_C_END


672: EXTERN_C_BEGIN
675: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
676: {
677:   PetscErrorCode    ierr;
678:   size_t            len;
679:   char              fname[PETSC_MAX_PATH_LEN],*gz;
680:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
681:   PetscBool         isstderr,isstdout;
682:   PetscMPIInt       rank;

685:   PetscViewerFileClose_ASCII(viewer);
686:   if (!name) return(0);
687:   PetscStrallocpy(name,&vascii->filename);

689:   /* Is this file to be compressed */
690:   vascii->storecompressed = PETSC_FALSE;
691:   PetscStrstr(vascii->filename,".gz",&gz);
692:   if (gz) {
693:     PetscStrlen(gz,&len);
694:     if (len == 3) {
695:       *gz = 0;
696:       vascii->storecompressed = PETSC_TRUE;
697:     }
698:   }
699:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
700:   if (!rank) {
701:     PetscStrcmp(name,"stderr",&isstderr);
702:     PetscStrcmp(name,"stdout",&isstdout);
703:     /* empty filename means stdout */
704:     if (name[0] == 0)  isstdout = PETSC_TRUE;
705:     if (isstderr)      vascii->fd = PETSC_STDERR;
706:     else if (isstdout) vascii->fd = PETSC_STDOUT;
707:     else {


710:       PetscFixFilename(name,fname);
711:       switch(vascii->mode) {
712:       case FILE_MODE_READ:
713:         vascii->fd = fopen(fname,"r");
714:         break;
715:       case FILE_MODE_WRITE:
716:         vascii->fd = fopen(fname,"w");
717:         break;
718:       case FILE_MODE_APPEND:
719:         vascii->fd = fopen(fname,"a");
720:         break;
721:       case FILE_MODE_UPDATE:
722:         vascii->fd = fopen(fname,"r+");
723:         if (!vascii->fd) {
724:           vascii->fd = fopen(fname,"w+");
725:         }
726:         break;
727:       case FILE_MODE_APPEND_UPDATE:
728:         /* I really want a file which is opened at the end for updating,
729:            not a+, which opens at the beginning, but makes writes at the end.
730:         */
731:         vascii->fd = fopen(fname,"r+");
732:         if (!vascii->fd) {
733:           vascii->fd = fopen(fname,"w+");
734:         } else {
735:           fseek(vascii->fd, 0, SEEK_END);
736:         }
737:         break;
738:       default:
739:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
740:       }
741:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
742:     }
743:   }
744: #if defined(PETSC_USE_LOG)
745:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
746: #endif
747:   return(0);
748: }
749: EXTERN_C_END

753: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
754: {
755:   PetscMPIInt       rank;
756:   PetscErrorCode    ierr;
757:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
758:   const char        *name;

761:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
762:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
763:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
764:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
765:   ovascii->fd  = vascii->fd;
766:   ovascii->tab = vascii->tab;

768:   vascii->sviewer = *outviewer;

770:   (*outviewer)->format     = viewer->format;
771:   (*outviewer)->iformat    = viewer->iformat;

773:   PetscObjectGetName((PetscObject)viewer,&name);
774:   PetscObjectSetName((PetscObject)(*outviewer),name);

776:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
777:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
778:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
779:   if (rank) {
780:     (*outviewer)->ops->flush = 0;
781:   } else {
782:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
783:   }
784:   return(0);
785: }

789: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
790: {
791:   PetscErrorCode    ierr;
792:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
793:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

796:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton never obtained from PetscViewer");
797:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate singleton");

799:   ascii->sviewer             = 0;
800:   vascii->fd                 = PETSC_STDOUT;
801:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
802:   PetscViewerDestroy(outviewer);
803:   PetscViewerFlush(viewer);
804:   return(0);
805: }

809: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
810: {
811:   PetscErrorCode    ierr;
812:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
813:   const char        *name;

816:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
817:   /* Note that we need to open vascii->filename for the subcomm:
818:      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
819:      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
820:      will return the current viewer, having increfed it.
821:    */
822:   PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
823:   if(*outviewer == viewer) return(0);
824:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;

826:   ovascii->tab = vascii->tab;
827:   vascii->sviewer = *outviewer;

829:   (*outviewer)->format     = viewer->format;
830:   (*outviewer)->iformat    = viewer->iformat;

832:   PetscObjectGetName((PetscObject)viewer,&name);
833:   PetscObjectSetName((PetscObject)(*outviewer),name);

835:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
836:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
837:   return(0);
838: }

842: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
843: {
844:   PetscErrorCode    ierr;
845:   PetscViewer_ASCII *oascii = (PetscViewer_ASCII *)(*outviewer)->data;
846:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

849:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
850:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"The given PetscViewer did not generate this subcomm viewer");

852:   ascii->sviewer             = 0;
853:   oascii->fd                 = PETSC_STDOUT;
854:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
855:   PetscViewerDestroy(outviewer);
856:   PetscViewerFlush(viewer);
857:   return(0);
858: }

860: EXTERN_C_BEGIN
863: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
864: {
865:   PetscViewer_ASCII *vascii;
866:   PetscErrorCode    ierr;

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

872:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
873:   viewer->ops->flush            = PetscViewerFlush_ASCII;
874:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
875:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
876:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
877:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;

879:   /* defaults to stdout unless set with PetscViewerFileSetName() */
880:   vascii->fd             = PETSC_STDOUT;
881:   vascii->mode           = FILE_MODE_WRITE;
882:   vascii->bviewer        = 0;
883:   vascii->sviewer        = 0;
884:   viewer->format         = PETSC_VIEWER_DEFAULT;
885:   viewer->iformat        = 0;
886:   vascii->tab            = 0;
887:   vascii->tab_store      = 0;
888:   vascii->filename       = 0;
889:   vascii->closefile      = PETSC_TRUE;

891:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
892:                                      PetscViewerFileSetName_ASCII);
893:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
894:                                      PetscViewerFileGetName_ASCII);
895:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
896:                                      PetscViewerFileGetMode_ASCII);
897:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
898:                                      PetscViewerFileSetMode_ASCII);

900:   return(0);
901: }
902: EXTERN_C_END


907: /*@C
908:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
909:     several processors.  Output of the first processor is followed by that of the 
910:     second, etc.

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

914:     Input Parameters:
915: +   viewer - the ASCII PetscViewer
916: -   format - the usual printf() format string 

918:     Level: intermediate

920:     Notes: You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.

922:     Fortran Note:
923:       Can only print a single character* string

925: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
926:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
927:           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()

929: @*/
930: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
931: {
932:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
933:   PetscErrorCode    ierr;
934:   PetscMPIInt       rank,size;
935:   PetscInt          tab = vascii->tab;
936:   MPI_Comm          comm;
937:   FILE              *fp;
938:   PetscBool         iascii;
939:   int               err;

944:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
945:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
946:   MPI_Comm_size(((PetscObject)viewer)->comm,&size);
947:   if (size > 1 && !vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIISynchronizedAllow() to allow this call");
948:   if (!viewer->ops->flush) return(0); /* This viewer obtained via PetscViewerGetSubcomm_ASCII(), should not participate. */

950:   comm = ((PetscObject)viewer)->comm;
951:   fp   = vascii->fd;
952:   MPI_Comm_rank(comm,&rank);

954:   /* First processor prints immediately to fp */
955:   if (!rank) {
956:     va_list Argp;

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

960:     va_start(Argp,format);
961:     (*PetscVFPrintf)(fp,format,Argp);
962:     err = fflush(fp);
963:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
964:     petsc_printfqueuefile = fp;
965:     if (petsc_history) {
966:       va_start(Argp,format);
967:       (*PetscVFPrintf)(petsc_history,format,Argp);
968:       err = fflush(petsc_history);
969:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
970:     }
971:     va_end(Argp);
972:   } else { /* other processors add to local queue */
973:     char        *string;
974:     va_list     Argp;
975:     size_t      fullLength;
976:     PrintfQueue next;

978:     PetscNew(struct _PrintfQueue,&next);
979:     if (petsc_printfqueue) {petsc_printfqueue->next = next; petsc_printfqueue = next;}
980:     else                   {petsc_printfqueuebase   = petsc_printfqueue = next;}
981:     petsc_printfqueuelength++;
982:     next->size = QUEUESTRINGSIZE;
983:     PetscMalloc(next->size*sizeof(char), &next->string);
984:     PetscMemzero(next->string,next->size);
985:     string = next->string;
986:     tab *= 2;
987:     while (tab--) {*string++ = ' ';}
988:     va_start(Argp,format);
989:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
990:     va_end(Argp);
991:   }
992:   return(0);
993: }