Actual source code: filev.c

petsc-3.5.4 2015-05-23
Report Typos and Errors
  2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I "petscviewer.h" I*/

  4: #define QUEUESTRINGSIZE 8192

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

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

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

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

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

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

 81: PetscErrorCode PetscViewerDestroy_ASCII_Singleton(PetscViewer viewer)
 82: {
 83:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 84:   PetscErrorCode    ierr;

 87:   PetscViewerRestoreSingleton(vascii->bviewer,&viewer);
 88:   vascii->bviewer = NULL;
 89:   return(0);
 90: }

 94: PetscErrorCode PetscViewerDestroy_ASCII_Subcomm(PetscViewer viewer)
 95: {
 96:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 97:   PetscErrorCode    ierr;

100:   PetscViewerRestoreSubcomm(vascii->subviewer,PetscObjectComm((PetscObject)viewer),&viewer);
101:   vascii->subviewer = NULL;
102:   return(0);
103: }

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

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

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

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

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

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

147:     Not Collective

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

152:     Level: intermediate

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

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

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

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

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: }

185: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
186: {
187:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

190:   vascii->mode = mode;
191:   return(0);
192: }

194: /*
195:    If petsc_history is on, then all Petsc*Printf() results are saved
196:    if the appropriate (usually .petschistory) file.
197: */
198: extern FILE *petsc_history;

202: /*@
203:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

207:     Input Parameters:
208: +    viewer - optained with PetscViewerASCIIOpen()
209: -    tabs - number of tabs

211:     Level: developer

213:     Fortran Note:
214:     This routine is not supported in Fortran.

216:   Concepts: PetscViewerASCII^formating
217:   Concepts: tab^setting

219: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
220:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
221:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
222: @*/
223: PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
224: {
225:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
226:   PetscBool         iascii;
227:   PetscErrorCode    ierr;

231:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
232:   if (iascii) ascii->tab = tabs;
233:   return(0);
234: }

238: /*@
239:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

241:     Not Collective, meaningful on first processor only.

243:     Input Parameters:
244: .    viewer - optained with PetscViewerASCIIOpen()
245:     Output Parameters:
246: .    tabs - number of tabs

248:     Level: developer

250:     Fortran Note:
251:     This routine is not supported in Fortran.

253:   Concepts: PetscViewerASCII^formating
254:   Concepts: tab^retrieval

256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
257:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259: @*/
260: PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
261: {
262:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
263:   PetscBool         iascii;
264:   PetscErrorCode    ierr;

268:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
269:   if (iascii && tabs) *tabs = ascii->tab;
270:   return(0);
271: }

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

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

280:     Input Parameters:
281: +    viewer - optained with PetscViewerASCIIOpen()
282: -    tabs - number of tabs

284:     Level: developer

286:     Fortran Note:
287:     This routine is not supported in Fortran.

289:   Concepts: PetscViewerASCII^formating
290:   Concepts: tab^setting

292: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
293:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
294:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
295: @*/
296: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
297: {
298:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
299:   PetscBool         iascii;
300:   PetscErrorCode    ierr;

304:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
305:   if (iascii) ascii->tab += tabs;
306:   return(0);
307: }

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

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

316:     Input Parameters:
317: +    viewer - optained with PetscViewerASCIIOpen()
318: -    tabs - number of tabs

320:     Level: developer

322:     Fortran Note:
323:     This routine is not supported in Fortran.

325:   Concepts: PetscViewerASCII^formating
326:   Concepts: tab^setting

328: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
329:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
330:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
331: @*/
332: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
333: {
334:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
335:   PetscBool         iascii;
336:   PetscErrorCode    ierr;

340:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
341:   if (iascii) ascii->tab -= tabs;
342:   return(0);
343: }

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

350:     Collective on PetscViewer

352:     Input Parameters:
353: +    viewer - optained with PetscViewerASCIIOpen()
354: -    allow - PETSC_TRUE to allow the synchronized printing

356:     Level: intermediate

358:   Concepts: PetscViewerASCII^formating
359:   Concepts: tab^setting

361: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
362:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
363:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
364: @*/
365: PetscErrorCode  PetscViewerASCIISynchronizedAllow(PetscViewer viewer,PetscBool allow)
366: {
367:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
368:   PetscBool         iascii;
369:   PetscErrorCode    ierr;

373:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
374:   if (iascii) ascii->allowsynchronized = allow;
375:   return(0);
376: }

380: /*@
381:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
382:      lines are tabbed.

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

386:     Input Parameters:
387: .    viewer - optained with PetscViewerASCIIOpen()

389:     Level: developer

391:     Fortran Note:
392:     This routine is not supported in Fortran.

394:   Concepts: PetscViewerASCII^formating
395:   Concepts: tab^setting

397: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
398:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
399:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
400: @*/
401: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
402: {
403:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
404:   PetscBool         iascii;
405:   PetscErrorCode    ierr;

409:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
410:   if (iascii) ascii->tab++;
411:   return(0);
412: }

416: /*@
417:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
418:      lines are tabbed.

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

422:     Input Parameters:
423: .    viewer - optained with PetscViewerASCIIOpen()

425:     Level: developer

427:     Fortran Note:
428:     This routine is not supported in Fortran.

430:   Concepts: PetscViewerASCII^formating
431:   Concepts: tab^setting

433: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
434:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
435:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
436: @*/
437: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
438: {
439:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
440:   PetscErrorCode    ierr;
441:   PetscBool         iascii;

445:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
446:   if (iascii) {
447:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
448:     ascii->tab--;
449:   }
450:   return(0);
451: }

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

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

460:     Input Parameters:
461: +    viewer - optained with PetscViewerASCIIOpen()
462: -    flg - PETSC_TRUE or PETSC_FALSE

464:     Level: developer

466:     Fortran Note:
467:     This routine is not supported in Fortran.

469:   Concepts: PetscViewerASCII^formating
470:   Concepts: tab^setting

472: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
473:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
474:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
475: @*/
476: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
477: {
478:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
479:   PetscBool         iascii;
480:   PetscErrorCode    ierr;

484:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
485:   if (iascii) {
486:     if (flg) ascii->tab = ascii->tab_store;
487:     else {
488:       ascii->tab_store = ascii->tab;
489:       ascii->tab       = 0;
490:     }
491:   }
492:   return(0);
493: }

495: /* ----------------------------------------------------------------------- */

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

501: /*@C
502:     PetscViewerASCIIPrintf - Prints to a file, only from the first
503:     processor in the PetscViewer

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

507:     Input Parameters:
508: +    viewer - optained with PetscViewerASCIIOpen()
509: -    format - the usual printf() format string

511:     Level: developer

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

517:   Concepts: PetscViewerASCII^printing
518:   Concepts: printing^to file
519:   Concepts: printf

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

538:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
539:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
540:   if (ascii->bviewer) {
541:     viewer      = ascii->bviewer;
542:     ascii       = (PetscViewer_ASCII*)viewer->data;
543:     fd          = ascii->fd;
544:     issingleton = PETSC_TRUE;
545:   }

547:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
548:   if (!rank) {
549:     va_list Argp;
550:     tab = intab;
551:     while (tab--) {
552:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
553:     }

555:     va_start(Argp,format);
556:     (*PetscVFPrintf)(fd,format,Argp);
557:     err  = fflush(fd);
558:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
559:     if (petsc_history) {
560:       va_start(Argp,format);
561:       tab = intab;
562:       while (tab--) {
563:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
564:       }
565:       (*PetscVFPrintf)(petsc_history,format,Argp);
566:       err  = fflush(petsc_history);
567:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
568:     }
569:     va_end(Argp);
570:   } else if (issingleton) {
571:     char        *string;
572:     va_list     Argp;
573:     size_t      fullLength;
574:     PrintfQueue next;

576:     PetscNew(&next);
577:     if (petsc_printfqueue) {
578:       petsc_printfqueue->next = next;
579:       petsc_printfqueue       = next;
580:     } else {
581:       petsc_printfqueuebase = petsc_printfqueue = next;
582:     }
583:     petsc_printfqueuelength++;
584:     next->size = QUEUESTRINGSIZE;
585:     PetscMalloc(next->size*sizeof(char), &next->string);
586:     PetscMemzero(next->string,next->size);
587:     string     = next->string;
588:     tab        = intab;
589:     tab       *= 2;
590:     while (tab--) {
591:       *string++ = ' ';
592:     }
593:     va_start(Argp,format);
594:     PetscVSNPrintf(string,next->size-2*ascii->tab,format,&fullLength,Argp);
595:     va_end(Argp);
596:   }
597:   return(0);
598: }

602: /*@C
603:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

605:     Collective on PetscViewer

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

611:     Level: advanced

613: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
614:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

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

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

630: /*@C
631:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

633:     Not Collective

635:   Input Parameter:
636: .  viewer - the PetscViewer; either ASCII or binary

638:   Output Parameter:
639: .  name - the name of the file it is using

641:     Level: advanced

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

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

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

658: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
659: {
660:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

663:   *name = vascii->filename;
664:   return(0);
665: }

669: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
670: {
671:   PetscErrorCode    ierr;
672:   size_t            len;
673:   char              fname[PETSC_MAX_PATH_LEN],*gz;
674:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
675:   PetscBool         isstderr,isstdout;
676:   PetscMPIInt       rank;

679:   PetscViewerFileClose_ASCII(viewer);
680:   if (!name) return(0);
681:   PetscStrallocpy(name,&vascii->filename);

683:   /* Is this file to be compressed */
684:   vascii->storecompressed = PETSC_FALSE;

686:   PetscStrstr(vascii->filename,".gz",&gz);
687:   if (gz) {
688:     PetscStrlen(gz,&len);
689:     if (len == 3) {
690:       *gz = 0;
691:       vascii->storecompressed = PETSC_TRUE;
692:     }
693:   }
694:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
695:   if (!rank) {
696:     PetscStrcmp(name,"stderr",&isstderr);
697:     PetscStrcmp(name,"stdout",&isstdout);
698:     /* empty filename means stdout */
699:     if (name[0] == 0)  isstdout = PETSC_TRUE;
700:     if (isstderr)      vascii->fd = PETSC_STDERR;
701:     else if (isstdout) vascii->fd = PETSC_STDOUT;
702:     else {


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

744: PetscErrorCode PetscViewerGetSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
745: {
746:   PetscMPIInt       rank;
747:   PetscErrorCode    ierr;
748:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
749:   const char        *name;

752:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Singleton already obtained from PetscViewer and not restored");
753:   PetscViewerCreate(PETSC_COMM_SELF,outviewer);
754:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
755:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
756:   ovascii->fd  = vascii->fd;
757:   ovascii->tab = vascii->tab;

759:   vascii->sviewer = *outviewer;

761:   (*outviewer)->format  = viewer->format;

763:   PetscObjectGetName((PetscObject)viewer,&name);
764:   PetscObjectSetName((PetscObject)(*outviewer),name);

766:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
767:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
768:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Singleton;
769:   if (rank) (*outviewer)->ops->flush = 0;
770:   else      (*outviewer)->ops->flush = PetscViewerFlush_ASCII_Singleton_0;
771:   return(0);
772: }

776: PetscErrorCode PetscViewerRestoreSingleton_ASCII(PetscViewer viewer,PetscViewer *outviewer)
777: {
778:   PetscErrorCode    ierr;
779:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)(*outviewer)->data;
780:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

786:   ascii->sviewer             = 0;
787:   vascii->fd                 = PETSC_STDOUT;
788:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
789:   PetscViewerDestroy(outviewer);
790:   PetscViewerFlush(viewer);
791:   return(0);
792: }

796: PetscErrorCode PetscViewerGetSubcomm_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
797: {
798:   PetscErrorCode    ierr;
799:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
800:   const char        *name;

803:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Subcomm viewer already obtained from PetscViewer and not restored");
804:   /* Note that we need to open vascii->filename for the subcomm:
805:      we can't count on reusing viewer's fd since the root in comm and subcomm may differ.
806:      Further, if the subcomm happens to be the same as comm, PetscViewerASCIIOpen() will
807:      will return the current viewer, having increfed it.
808:    */
809:   PetscViewerASCIIOpen(subcomm,vascii->filename, outviewer);
810:   if (*outviewer == viewer) return(0);
811:   ovascii = (PetscViewer_ASCII*)(*outviewer)->data;

813:   ovascii->tab    = vascii->tab;
814:   vascii->sviewer = *outviewer;

816:   (*outviewer)->format  = viewer->format;

818:   PetscObjectGetName((PetscObject)viewer,&name);
819:   PetscObjectSetName((PetscObject)(*outviewer),name);

821:   ((PetscViewer_ASCII*)((*outviewer)->data))->subviewer = viewer;

823:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_Subcomm;
824:   return(0);
825: }

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

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

839:   ascii->sviewer             = 0;
840:   oascii->fd                 = PETSC_STDOUT;
841:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;

843:   PetscViewerDestroy(outviewer);
844:   PetscViewerFlush(viewer);
845:   return(0);
846: }

850: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
851: {
852:   PetscErrorCode    ierr;
853:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

856:   if (ascii->filename) {
857:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
858:   }
859:   return(0);
860: }

864: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
865: {
866:   PetscViewer_ASCII *vascii;
867:   PetscErrorCode    ierr;

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

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

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

892:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
893:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
894:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
895:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
896:   return(0);
897: }


902: /*@C
903:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
904:     several processors.  Output of the first processor is followed by that of the
905:     second, etc.

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

909:     Input Parameters:
910: +   viewer - the ASCII PetscViewer
911: -   format - the usual printf() format string

913:     Level: intermediate

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

917:     Fortran Note:
918:       Can only print a single character* string

920: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
921:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
922:           PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedAllow()

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

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

945:   PetscObjectGetComm((PetscObject)viewer,&comm);
946:   fp   = vascii->fd;
947:   MPI_Comm_rank(comm,&rank);

949:   /* First processor prints immediately to fp */
950:   if (!rank) {
951:     va_list Argp;

953:     while (tab--) {
954:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
955:     }

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

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