Actual source code: filev.c

  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 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(),
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:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
253:   if (iascii) {
254:     ascii->tab = tabs;
255:   }
256:   return(0);
257: }

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

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

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

270:     Level: developer

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

275:   Concepts: PetscViewerASCII^formating
276:   Concepts: tab^setting

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

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

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

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

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

308:     Level: developer

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

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

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

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

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

340:     Collective on PetscViewer

342:     Input Parameters:
343: +    viewer - optained with PetscViewerASCIIOpen()
344: -    allow - PETSC_TRUE to allow the synchronized printing

346:     Level: intermediate

348:   Concepts: PetscViewerASCII^formating
349:   Concepts: tab^setting

351: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
352:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
353:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
354: @*/
355: PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
356: {
357:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
358:   PetscBool         iascii;
359:   PetscErrorCode    ierr;

363:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
364:   if (iascii) {
365:     ascii->allowsynchronized = allow;
366:   }
367:   return(0);
368: }

372: /*@
373:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
374:      lines are tabbed.

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

378:     Input Parameters:
379: .    viewer - optained with PetscViewerASCIIOpen()

381:     Level: developer

383:     Fortran Note:
384:     This routine is not supported in Fortran.

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

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

401:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
402:   if (iascii) {
403:     ascii->tab++;
404:   }
405:   return(0);
406: }

410: /*@
411:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
412:      lines are tabbed.

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

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

419:     Level: developer

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

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

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

439:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
440:   if (iascii) {
441:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
442:     ascii->tab--;
443:   }
444:   return(0);
445: }

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

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

454:     Input Parameters:
455: +    viewer - optained with PetscViewerASCIIOpen()
456: -    flg - PETSC_TRUE or PETSC_FALSE

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:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
468:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
469: @*/
470: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool  flg)
471: {
472:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
473:   PetscBool         iascii;
474:   PetscErrorCode    ierr;

478:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
479:   if (iascii) {
480:     if (flg) {
481:       ascii->tab       = ascii->tab_store;
482:     } else {
483:       ascii->tab_store = ascii->tab;
484:       ascii->tab       = 0;
485:     }
486:   }
487:   return(0);
488: }

490: /* ----------------------------------------------------------------------- */

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

496: /*@C
497:     PetscViewerASCIIPrintf - Prints to a file, only from the first
498:     processor in the PetscViewer

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

502:     Input Parameters:
503: +    viewer - optained with PetscViewerASCIIOpen()
504: -    format - the usual printf() format string 

506:     Level: developer

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

512:   Concepts: PetscViewerASCII^printing
513:   Concepts: printing^to file
514:   Concepts: printf

516: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
517:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
518:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIISynchronizedAllow()
519: @*/
520: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
521: {
522:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
523:   PetscMPIInt       rank;
524:   PetscInt          tab;
525:   PetscErrorCode    ierr;
526:   FILE              *fd = ascii->fd;
527:   PetscBool         iascii;
528:   int               err;

533:   PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
534:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");

536:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
537:   if (ascii->bviewer) {MPI_Comm_rank(((PetscObject)ascii->bviewer)->comm,&rank);}
538:   if (!rank) {
539:     va_list Argp;
540:     if (ascii->bviewer) {
541:       queuefile = fd;
542:     }

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

547:     va_start(Argp,format);
548:     (*PetscVFPrintf)(fd,format,Argp);
549:     err = fflush(fd);
550:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
551:     if (petsc_history) {
552:       va_start(Argp,format);
553:       tab = ascii->tab;
554:       while (tab--) {PetscFPrintf(PETSC_COMM_SELF,fd,"  ");}
555:       (*PetscVFPrintf)(petsc_history,format,Argp);
556:       err = fflush(petsc_history);
557:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
558:     }
559:     va_end(Argp);
560:   } else if (ascii->bviewer) { /* this is a singleton PetscViewer that is not on process 0 */
561:     va_list     Argp;
562:     size_t      fullLength;
563:     char        *string;

565:     PrintfQueue next;
566:     PetscNew(struct _PrintfQueue,&next);
567:     if (queue) {queue->next = next; queue = next;}
568:     else       {queuebase   = queue = next;}
569:     queuelength++;
570:     next->size = QUEUESTRINGSIZE;
571:     PetscMalloc(next->size*sizeof(char), &next->string);
572:     PetscMemzero(next->string,next->size);
573:     string = next->string;
574:     tab = 2*ascii->tab;
575:     while (tab--) {*string++ = ' ';}
576:     va_start(Argp,format);
577:     PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
578:     va_end(Argp);
579:   }
580:   return(0);
581: }

585: /*@C
586:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

588:     Collective on PetscViewer

590:   Input Parameters:
591: +  viewer - the PetscViewer; either ASCII or binary
592: -  name - the name of the file it should use

594:     Level: advanced

596: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
597:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

599: @*/
600: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
601: {

607:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
608:   return(0);
609: }

613: /*@C
614:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

616:     Not Collective

618:   Input Parameter:
619: .  viewer - the PetscViewer; either ASCII or binary

621:   Output Parameter:
622: .  name - the name of the file it is using

624:     Level: advanced

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

628: @*/
629: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
630: {

635:   PetscTryMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char **),(viewer,name));
636:   return(0);
637: }

639: EXTERN_C_BEGIN
642: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
643: {
644:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

647:   *name = vascii->filename;
648:   return(0);
649: }
650: EXTERN_C_END


653: EXTERN_C_BEGIN
656: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
657: {
658:   PetscErrorCode    ierr;
659:   size_t            len;
660:   char              fname[PETSC_MAX_PATH_LEN],*gz;
661:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
662:   PetscBool         isstderr,isstdout;
663:   PetscMPIInt       rank;

666:   PetscViewerFileClose_ASCII(viewer);
667:   if (!name) return(0);
668:   PetscStrallocpy(name,&vascii->filename);

670:   /* Is this file to be compressed */
671:   vascii->storecompressed = PETSC_FALSE;
672:   PetscStrstr(vascii->filename,".gz",&gz);
673:   if (gz) {
674:     PetscStrlen(gz,&len);
675:     if (len == 3) {
676:       *gz = 0;
677:       vascii->storecompressed = PETSC_TRUE;
678:     }
679:   }
680:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
681:   if (!rank) {
682:     PetscStrcmp(name,"stderr",&isstderr);
683:     PetscStrcmp(name,"stdout",&isstdout);
684:     /* empty filename means stdout */
685:     if (name[0] == 0)  isstdout = PETSC_TRUE;
686:     if (isstderr)      vascii->fd = PETSC_STDERR;
687:     else if (isstdout) vascii->fd = PETSC_STDOUT;
688:     else {


691:       PetscFixFilename(name,fname);
692:       switch(vascii->mode) {
693:       case FILE_MODE_READ:
694:         vascii->fd = fopen(fname,"r");
695:         break;
696:       case FILE_MODE_WRITE:
697:         vascii->fd = fopen(fname,"w");
698:         break;
699:       case FILE_MODE_APPEND:
700:         vascii->fd = fopen(fname,"a");
701:         break;
702:       case FILE_MODE_UPDATE:
703:         vascii->fd = fopen(fname,"r+");
704:         if (!vascii->fd) {
705:           vascii->fd = fopen(fname,"w+");
706:         }
707:         break;
708:       case FILE_MODE_APPEND_UPDATE:
709:         /* I really want a file which is opened at the end for updating,
710:            not a+, which opens at the beginning, but makes writes at the end.
711:         */
712:         vascii->fd = fopen(fname,"r+");
713:         if (!vascii->fd) {
714:           vascii->fd = fopen(fname,"w+");
715:         } else {
716:           fseek(vascii->fd, 0, SEEK_END);
717:         }
718:         break;
719:       default:
720:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
721:       }
722:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
723:     }
724:   }
725: #if defined(PETSC_USE_LOG)
726:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
727: #endif
728:   return(0);
729: }
730: EXTERN_C_END

734: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
735: {
736:   PetscMPIInt       rank;
737:   PetscErrorCode    ierr;
738:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
739:   const char        *name;

742:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
743:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
744:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
745:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
746:   ovascii->fd  = vascii->fd;
747:   ovascii->tab = vascii->tab;

749:   vascii->sviewer = *outviewer;

751:   (*outviewer)->format     = viewer->format;
752:   (*outviewer)->iformat    = viewer->iformat;

754:   PetscObjectGetName((PetscObject)viewer,&name);
755:   PetscObjectSetName((PetscObject)(*outviewer),name);

757:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
758:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
759:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
760:   if (rank) {
761:     (*outviewer)->ops->flush = 0;
762:   } else {
763:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
764:   }
765:   return(0);
766: }

770: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
771: {
772:   PetscErrorCode    ierr;
773:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
774:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

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

780:   ascii->sviewer             = 0;
781:   vascii->fd                 = PETSC_STDOUT;
782:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
783:   PetscViewerDestroy(outviewer);
784:   PetscViewerFlush(viewer);
785:   return(0);
786: }

790: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
791: {
792:   PetscMPIInt       rank;
793:   PetscErrorCode    ierr;
794:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data,*ovascii;
795:   const char        *name;

798:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm already obtained from PetscViewer and not restored");
799:   PetscViewerCreate(subcomm,outviewer);
800:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
801:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
802:   ovascii->fd  = vascii->fd;
803:   ovascii->tab = vascii->tab;

805:   vascii->sviewer = *outviewer;

807:   (*outviewer)->format     = viewer->format;
808:   (*outviewer)->iformat    = viewer->iformat;

810:   PetscObjectGetName((PetscObject)viewer,&name);
811:   PetscObjectSetName((PetscObject)(*outviewer),name);

813:   MPI_Comm_rank(((PetscObject)viewer)->comm,&rank);
814:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
815:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
816:   /* following might not be correct??? */
817:   if (rank) {
818:     (*outviewer)->ops->flush = 0;
819:   } else {
820:     (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
821:   }
822:   return(0);
823: }

827: PetscErrorCode PetscViewerRestoreSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
828: {
829:   PetscErrorCode    ierr;
830:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)(*outviewer)->data;
831:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII *)viewer->data;

834:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm never obtained from PetscViewer");
835:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate subcomm");

837:   ascii->sviewer             = 0;
838:   vascii->fd                 = PETSC_STDOUT;
839:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
840:   PetscViewerDestroy(outviewer);
841:   PetscViewerFlush(viewer);
842:   return(0);
843: }

845: EXTERN_C_BEGIN
848: PetscErrorCode  PetscViewerCreate_ASCII(PetscViewer viewer)
849: {
850:   PetscViewer_ASCII *vascii;
851:   PetscErrorCode    ierr;

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

857:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
858:   viewer->ops->flush            = PetscViewerFlush_ASCII;
859:   viewer->ops->getsingleton     = PetscViewerGetSingleton_ASCII;
860:   viewer->ops->restoresingleton = PetscViewerRestoreSingleton_ASCII;
861:   viewer->ops->getsubcomm       = PetscViewerGetSubcomm_ASCII;
862:   viewer->ops->restoresubcomm   = PetscViewerRestoreSubcomm_ASCII;

864:   /* defaults to stdout unless set with PetscViewerFileSetName() */
865:   vascii->fd             = PETSC_STDOUT;
866:   vascii->mode           = FILE_MODE_WRITE;
867:   vascii->bviewer        = 0;
868:   vascii->sviewer        = 0;
869:   viewer->format         = PETSC_VIEWER_DEFAULT;
870:   viewer->iformat        = 0;
871:   vascii->tab            = 0;
872:   vascii->tab_store      = 0;
873:   vascii->filename       = 0;
874:   vascii->closefile      = PETSC_TRUE;

876:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetName_C","PetscViewerFileSetName_ASCII",
877:                                      PetscViewerFileSetName_ASCII);
878:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetName_C","PetscViewerFileGetName_ASCII",
879:                                      PetscViewerFileGetName_ASCII);
880:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileGetMode_C","PetscViewerFileGetMode_ASCII",
881:                                      PetscViewerFileGetMode_ASCII);
882:   PetscObjectComposeFunctionDynamic((PetscObject)viewer,"PetscViewerFileSetMode_C","PetscViewerFileSetMode_ASCII",
883:                                      PetscViewerFileSetMode_ASCII);

885:   return(0);
886: }
887: EXTERN_C_END


892: /*@C
893:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
894:     several processors.  Output of the first processor is followed by that of the 
895:     second, etc.

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

899:     Input Parameters:
900: +   viewer - the ASCII PetscViewer
901: -   format - the usual printf() format string 

903:     Level: intermediate

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

907:     Fortran Note:
908:       Can only print a single character* string

910: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
911:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
912:           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()

914: @*/
915: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
916: {
917:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII *)viewer->data;
918:   PetscErrorCode    ierr;
919:   PetscMPIInt       rank,size;
920:   PetscInt          tab = vascii->tab;
921:   MPI_Comm          comm;
922:   FILE              *fp;
923:   PetscBool         iascii;
924:   int               err;

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

935:   comm = ((PetscObject)viewer)->comm;
936:   fp   = vascii->fd;
937:   MPI_Comm_rank(comm,&rank);
938:   if (vascii->bviewer) {MPI_Comm_rank(((PetscObject)vascii->bviewer)->comm,&rank);}
939: 

941:   /* First processor prints immediately to fp */
942:   if (!rank) {
943:     va_list Argp;

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

947:     va_start(Argp,format);
948:     (*PetscVFPrintf)(fp,format,Argp);
949:     err = fflush(fp);
950:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
951:     queuefile = fp;
952:     if (petsc_history) {
953:       va_start(Argp,format);
954:       (*PetscVFPrintf)(petsc_history,format,Argp);
955:       err = fflush(petsc_history);
956:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
957:     }
958:     va_end(Argp);
959:   } else { /* other processors add to local queue */
960:     char        *string;
961:     va_list     Argp;
962:     size_t      fullLength;
963:     PrintfQueue next;

965:     PetscNew(struct _PrintfQueue,&next);
966:     if (queue) {queue->next = next; queue = next;}
967:     else       {queuebase   = queue = next;}
968:     queuelength++;
969:     next->size = QUEUESTRINGSIZE;
970:     PetscMalloc(next->size*sizeof(char), &next->string);
971:     PetscMemzero(next->string,next->size);
972:     string = next->string;
973:     tab *= 2;
974:     while (tab--) {*string++ = ' ';}
975:     va_start(Argp,format);
976:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
977:     va_end(Argp);
978:   }
979:   return(0);
980: }