Actual source code: filev.c

petsc-3.7.3 2016-08-01
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:       if (vlink->next) {
 64:         MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
 65:       } else {
 66:         MPI_Attr_delete(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
 67:       }
 68:       PetscFree(vlink);
 69:     } else {
 70:       while (vlink && vlink->next) {
 71:         if (vlink->next->viewer == viewer) {
 72:           PetscViewerLink *nv = vlink->next;
 73:           vlink->next = vlink->next->next;
 74:           PetscFree(nv);
 75:         }
 76:         vlink = vlink->next;
 77:       }
 78:     }
 79:   }
 80:   return(0);
 81: }

 85: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
 86: {
 87:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 88:   PetscErrorCode    ierr;

 91:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
 92:   return(0);
 93: }

 97: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
 98: {
 99:   PetscErrorCode    ierr;
100:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
101:   int               err;
102:   MPI_Comm          comm;
103:   PetscMPIInt       rank,size;
104:   FILE              *fd = vascii->fd;

107:   PetscObjectGetComm((PetscObject)viewer,&comm);
108:   MPI_Comm_rank(comm,&rank);
109:   MPI_Comm_size(comm,&size);

111:   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
112:     err = fflush(vascii->fd);
113:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
114:   }

116:   if (vascii->allowsynchronized) {
117:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
118:     char          *message;
119:     MPI_Status    status;

121:     PetscCommDuplicate(comm,&comm,&tag);

123:     /* First processor waits for messages from all other processors */
124:     if (!rank) {
125:       /* flush my own messages that I may have queued up */
126:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
127:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
128:         if (!vascii->bviewer) {
129:           PetscFPrintf(comm,fd,"%s",next->string);
130:         } else {
131:           PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);
132:         }
133:         previous = next;
134:         next     = next->next;
135:         PetscFree(previous->string);
136:         PetscFree(previous);
137:       }
138:       vascii->petsc_printfqueue       = 0;
139:       vascii->petsc_printfqueuelength = 0;
140:       for (i=1; i<size; i++) {
141:         /* to prevent a flood of messages to process zero, request each message separately */
142:         MPI_Send(&dummy,1,MPI_INT,i,tag,comm);
143:         MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);
144:         for (j=0; j<n; j++) {
145:           PetscMPIInt size = 0;

147:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
148:           PetscMalloc1(size, &message);
149:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
150:           if (!vascii->bviewer) {
151:             PetscFPrintf(comm,fd,"%s",message);
152:           } else {
153:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
154:           }
155:           PetscFree(message);
156:         }
157:       }
158:     } else { /* other processors send queue to processor 0 */
159:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

161:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
162:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
163:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
164:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
165:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
166:         previous = next;
167:         next     = next->next;
168:         PetscFree(previous->string);
169:         PetscFree(previous);
170:       }
171:       vascii->petsc_printfqueue       = 0;
172:       vascii->petsc_printfqueuelength = 0;
173:     }
174:     PetscCommDestroy(&comm);
175:   }
176:   return(0);
177: }

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

184:     Not Collective

186: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
187: -   fd - file pointer

189:     Level: intermediate

191:     Fortran Note:
192:     This routine is not supported in Fortran.

194:   Concepts: PetscViewer^file pointer
195:   Concepts: file pointer^getting from PetscViewer

197: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
198:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
199: @*/
200: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
201: {
202:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

205:   *fd = vascii->fd;
206:   return(0);
207: }

211: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
212: {
213:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

216:   *mode = vascii->mode;
217:   return(0);
218: }

222: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
223: {
224:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

227:   vascii->mode = mode;
228:   return(0);
229: }

231: /*
232:    If petsc_history is on, then all Petsc*Printf() results are saved
233:    if the appropriate (usually .petschistory) file.
234: */
235: extern FILE *petsc_history;

239: /*@
240:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

244:     Input Parameters:
245: +    viewer - obtained with PetscViewerASCIIOpen()
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^setting

256: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
257:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
258:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
259: @*/
260: PetscErrorCode  PetscViewerASCIISetTab(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) ascii->tab = tabs;
270:   return(0);
271: }

275: /*@
276:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

278:     Not Collective, meaningful on first processor only.

280:     Input Parameters:
281: .    viewer - obtained with PetscViewerASCIIOpen()
282:     Output Parameters:
283: .    tabs - number of tabs

285:     Level: developer

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

290:   Concepts: PetscViewerASCII^formating
291:   Concepts: tab^retrieval

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

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

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

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

317:     Input Parameters:
318: +    viewer - obtained with PetscViewerASCIIOpen()
319: -    tabs - number of tabs

321:     Level: developer

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

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

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

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

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

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

353:     Input Parameters:
354: +    viewer - obtained with PetscViewerASCIIOpen()
355: -    tabs - number of tabs

357:     Level: developer

359:     Fortran Note:
360:     This routine is not supported in Fortran.

362:   Concepts: PetscViewerASCII^formating
363:   Concepts: tab^setting

365: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
366:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
367:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
368: @*/
369: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
370: {
371:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
372:   PetscBool         iascii;
373:   PetscErrorCode    ierr;

377:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
378:   if (iascii) ascii->tab -= tabs;
379:   return(0);
380: }

384: /*@C
385:     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer

387:     Collective on PetscViewer

389:     Input Parameters:
390: .    viewer - obtained with PetscViewerASCIIOpen()

392:     Level: intermediate

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

397: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
398:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
399:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
400: @*/
401: PetscErrorCode  PetscViewerASCIIPushSynchronized(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->allowsynchronized++;
411:   return(0);
412: }

416: /*@C
417:     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer

419:     Collective on PetscViewer

421:     Input Parameters:
422: .    viewer - obtained with PetscViewerASCIIOpen()

424:     Level: intermediate

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

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

441:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
442:   if (iascii) {
443:     ascii->allowsynchronized--;
444:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
445:   }
446:   return(0);
447: }

451: /*@
452:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
453:      lines are tabbed.

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

457:     Input Parameters:
458: .    viewer - obtained with PetscViewerASCIIOpen()

460:     Level: developer

462:     Fortran Note:
463:     This routine is not supported in Fortran.

465:   Concepts: PetscViewerASCII^formating
466:   Concepts: tab^setting

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

480:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
481:   if (iascii) ascii->tab++;
482:   return(0);
483: }

487: /*@
488:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
489:      lines are tabbed.

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

493:     Input Parameters:
494: .    viewer - obtained with PetscViewerASCIIOpen()

496:     Level: developer

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

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

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

516:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
517:   if (iascii) {
518:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
519:     ascii->tab--;
520:   }
521:   return(0);
522: }

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

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

531:     Input Parameters:
532: +    viewer - obtained with PetscViewerASCIIOpen()
533: -    flg - PETSC_TRUE or PETSC_FALSE

535:     Level: developer

537:     Fortran Note:
538:     This routine is not supported in Fortran.

540:   Concepts: PetscViewerASCII^formating
541:   Concepts: tab^setting

543: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
544:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
545:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
546: @*/
547: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
548: {
549:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
550:   PetscBool         iascii;
551:   PetscErrorCode    ierr;

555:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
556:   if (iascii) {
557:     if (flg) ascii->tab = ascii->tab_store;
558:     else {
559:       ascii->tab_store = ascii->tab;
560:       ascii->tab       = 0;
561:     }
562:   }
563:   return(0);
564: }

566: /* ----------------------------------------------------------------------- */


571: /*@C
572:     PetscViewerASCIIPrintf - Prints to a file, only from the first
573:     processor in the PetscViewer

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

577:     Input Parameters:
578: +    viewer - obtained with PetscViewerASCIIOpen()
579: -    format - the usual printf() format string

581:     Level: developer

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

587:   Concepts: PetscViewerASCII^printing
588:   Concepts: printing^to file
589:   Concepts: printf

591: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
592:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
593:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
594: @*/
595: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
596: {
597:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
598:   PetscMPIInt       rank;
599:   PetscInt          tab,intab = ascii->tab;
600:   PetscErrorCode    ierr;
601:   FILE              *fd = ascii->fd;
602:   PetscBool         iascii;
603:   int               err;

608:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
609:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
610:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
611:   if (rank) return(0);

613:   if (ascii->bviewer) { /* pass string up to parent viewer */
614:     char        *string;
615:     va_list     Argp;
616:     size_t      fullLength;

618:     PetscCalloc1(QUEUESTRINGSIZE, &string);
619:     va_start(Argp,format);
620:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
621:     va_end(Argp);
622:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
623:     PetscFree(string);
624:   } else { /* write directly to file */
625:     va_list Argp;
626:     /* flush my own messages that I may have queued up */
627:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
628:     PetscInt    i;
629:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
630:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
631:       previous = next;
632:       next     = next->next;
633:       PetscFree(previous->string);
634:       PetscFree(previous);
635:     }
636:     ascii->petsc_printfqueue       = 0;
637:     ascii->petsc_printfqueuelength = 0;
638:     tab = intab;
639:     while (tab--) {
640:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
641:     }

643:     va_start(Argp,format);
644:     (*PetscVFPrintf)(fd,format,Argp);
645:     err  = fflush(fd);
646:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
647:     if (petsc_history) {
648:       va_start(Argp,format);
649:       tab = intab;
650:       while (tab--) {
651:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
652:       }
653:       (*PetscVFPrintf)(petsc_history,format,Argp);
654:       err  = fflush(petsc_history);
655:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
656:     }
657:     va_end(Argp);
658:   }
659:   return(0);
660: }

664: /*@C
665:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

667:     Collective on PetscViewer

669:   Input Parameters:
670: +  viewer - the PetscViewer; either ASCII or binary
671: -  name - the name of the file it should use

673:     Level: advanced

675: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
676:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

678: @*/
679: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
680: {

686:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
687:   return(0);
688: }

692: /*@C
693:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

695:     Not Collective

697:   Input Parameter:
698: .  viewer - the PetscViewer; either ASCII or binary

700:   Output Parameter:
701: .  name - the name of the file it is using

703:     Level: advanced

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

707: @*/
708: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
709: {

714:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
715:   return(0);
716: }

720: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
721: {
722:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

725:   *name = vascii->filename;
726:   return(0);
727: }

731: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
732: {
733:   PetscErrorCode    ierr;
734:   size_t            len;
735:   char              fname[PETSC_MAX_PATH_LEN],*gz;
736:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
737:   PetscBool         isstderr,isstdout;
738:   PetscMPIInt       rank;

741:   PetscViewerFileClose_ASCII(viewer);
742:   if (!name) return(0);
743:   PetscStrallocpy(name,&vascii->filename);

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

748:   PetscStrstr(vascii->filename,".gz",&gz);
749:   if (gz) {
750:     PetscStrlen(gz,&len);
751:     if (len == 3) {
752:       *gz = 0;
753:       vascii->storecompressed = PETSC_TRUE;
754:     }
755:   }
756:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
757:   if (!rank) {
758:     PetscStrcmp(name,"stderr",&isstderr);
759:     PetscStrcmp(name,"stdout",&isstdout);
760:     /* empty filename means stdout */
761:     if (name[0] == 0)  isstdout = PETSC_TRUE;
762:     if (isstderr)      vascii->fd = PETSC_STDERR;
763:     else if (isstdout) vascii->fd = PETSC_STDOUT;
764:     else {


767:       PetscFixFilename(name,fname);
768:       switch (vascii->mode) {
769:       case FILE_MODE_READ:
770:         vascii->fd = fopen(fname,"r");
771:         break;
772:       case FILE_MODE_WRITE:
773:         vascii->fd = fopen(fname,"w");
774:         break;
775:       case FILE_MODE_APPEND:
776:         vascii->fd = fopen(fname,"a");
777:         break;
778:       case FILE_MODE_UPDATE:
779:         vascii->fd = fopen(fname,"r+");
780:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
781:         break;
782:       case FILE_MODE_APPEND_UPDATE:
783:         /* I really want a file which is opened at the end for updating,
784:            not a+, which opens at the beginning, but makes writes at the end.
785:         */
786:         vascii->fd = fopen(fname,"r+");
787:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
788:         else {
789:           fseek(vascii->fd, 0, SEEK_END);
790:         }
791:         break;
792:       default:
793:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
794:       }
795:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
796:     }
797:   }
798: #if defined(PETSC_USE_LOG)
799:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
800: #endif
801:   return(0);
802: }

806: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
807: {
808:   PetscMPIInt       rank;
809:   PetscErrorCode    ierr;
810:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

813:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
814:   PetscViewerASCIIPushSynchronized(viewer);
815:   PetscViewerCreate(subcomm,outviewer);
816:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
817:   PetscViewerASCIIPushSynchronized(*outviewer);
818:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
819:   ovascii->fd  = vascii->fd;
820:   ovascii->tab = vascii->tab;
821:   ovascii->closefile = PETSC_FALSE;

823:   vascii->sviewer = *outviewer;

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

827:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
828:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
829:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
830:   return(0);
831: }

835: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
836: {
837:   PetscErrorCode    ierr;
838:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

841:   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
842:   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");

844:   ascii->sviewer             = 0;
845:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
846:   PetscViewerDestroy(outviewer);
847:   return(0);
848: }

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

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

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

872:   PetscNewLog(viewer,&vascii);
873:   viewer->data = (void*)vascii;

875:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
876:   viewer->ops->flush            = PetscViewerFlush_ASCII;
877:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
878:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
879:   viewer->ops->view             = PetscViewerView_ASCII;
880:   viewer->ops->read             = PetscViewerASCIIRead;

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

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

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(), PetscViewerASCIIPushSynchronized()

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

939:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
940:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
941:   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");

943:   PetscObjectGetComm((PetscObject)viewer,&comm);
944:   MPI_Comm_rank(comm,&rank);

946:   if (vascii->bviewer) {
947:     hasbviewer = PETSC_TRUE;
948:     if (!rank) {
949:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
950:       PetscObjectGetComm((PetscObject)viewer,&comm);
951:       MPI_Comm_rank(comm,&rank);
952:     }
953:   }

955:   fp   = vascii->fd;

957:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
958:     va_list Argp;
959:     /* flush my own messages that I may have queued up */
960:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
961:     PetscInt    i;
962:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
963:       PetscFPrintf(comm,fp,"%s",next->string);
964:       previous = next;
965:       next     = next->next;
966:       PetscFree(previous->string);
967:       PetscFree(previous);
968:     }
969:     vascii->petsc_printfqueue       = 0;
970:     vascii->petsc_printfqueuelength = 0;

972:     while (tab--) {
973:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
974:     }

976:     va_start(Argp,format);
977:     (*PetscVFPrintf)(fp,format,Argp);
978:     err  = fflush(fp);
979:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
980:     if (petsc_history) {
981:       va_start(Argp,format);
982:       (*PetscVFPrintf)(petsc_history,format,Argp);
983:       err  = fflush(petsc_history);
984:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
985:     }
986:     va_end(Argp);
987:   } else { /* other processors add to queue */
988:     char        *string;
989:     va_list     Argp;
990:     size_t      fullLength;
991:     PrintfQueue next;

993:     PetscNew(&next);
994:     if (vascii->petsc_printfqueue) {
995:       vascii->petsc_printfqueue->next = next;
996:       vascii->petsc_printfqueue       = next;
997:     } else {
998:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
999:     }
1000:     vascii->petsc_printfqueuelength++;
1001:     next->size = QUEUESTRINGSIZE;
1002:     PetscMalloc1(next->size, &next->string);
1003:     PetscMemzero(next->string,next->size);
1004:     string     = next->string;
1005:     tab       *= 2;
1006:     while (tab--) {
1007:       *string++ = ' ';
1008:     }
1009:     va_start(Argp,format);
1010:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1011:     va_end(Argp);
1012:   }
1013:   return(0);
1014: }

1018: /*@C
1019:    PetscViewerASCIIRead - Reads from am ASCII file

1021:    Collective on MPI_Comm

1023:    Input Parameters:
1024: +  viewer - the ascii viewer
1025: .  data - location to write the data
1026: .  num - number of items of data to read
1027: -  datatype - type of data to read

1029:    Output Parameters:
1030: .  count - number of items of data actually read, or NULL

1032:    Level: beginner

1034:    Concepts: ascii files

1036: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1037:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1038:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1039: @*/
1040: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1041: {
1042:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1043:   FILE              *fd = vascii->fd;
1044:   PetscInt           i;
1045:   int                ret = 0;

1049:   for (i=0; i<num; i++) {
1050:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1051:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1052:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1053:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1054:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1055:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1056:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1057:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1058:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1059:   }
1060:   if (count) *count = i;
1061:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1062:   return(0);
1063: }