Actual source code: filev.c

petsc-master 2017-02-20
Report Typos and Errors

  2:  #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>

  4: #define QUEUESTRINGSIZE 8192

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

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

 38: /* ----------------------------------------------------------------------*/
 39: PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
 40: {
 41:   PetscErrorCode    ierr;
 42:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 43:   PetscViewerLink   *vlink;
 44:   PetscBool         flg;

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

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

 56:   MPI_Attr_get(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
 57:   if (flg) {
 58:     if (vlink && vlink->viewer == viewer) {
 59:       if (vlink->next) {
 60:         MPI_Attr_put(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
 61:       } else {
 62:         MPI_Attr_delete(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
 63:       }
 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: }

 79: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
 80: {
 81:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 82:   PetscErrorCode    ierr;

 85:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
 86:   return(0);
 87: }

 89: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
 90: {
 91:   PetscErrorCode    ierr;
 92:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 93:   int               err;
 94:   MPI_Comm          comm;
 95:   PetscMPIInt       rank,size;
 96:   FILE              *fd = vascii->fd;

 99:   PetscObjectGetComm((PetscObject)viewer,&comm);
100:   MPI_Comm_rank(comm,&rank);
101:   MPI_Comm_size(comm,&size);

103:   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
104:     err = fflush(vascii->fd);
105:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
106:   }

108:   if (vascii->allowsynchronized) {
109:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
110:     char          *message;
111:     MPI_Status    status;

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

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

139:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
140:           PetscMalloc1(size, &message);
141:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
142:           if (!vascii->bviewer) {
143:             PetscFPrintf(comm,fd,"%s",message);
144:           } else {
145:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
146:           }
147:           PetscFree(message);
148:         }
149:       }
150:     } else { /* other processors send queue to processor 0 */
151:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

153:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
154:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
155:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
156:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
157:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
158:         previous = next;
159:         next     = next->next;
160:         PetscFree(previous->string);
161:         PetscFree(previous);
162:       }
163:       vascii->petsc_printfqueue       = 0;
164:       vascii->petsc_printfqueuelength = 0;
165:     }
166:     PetscCommDestroy(&comm);
167:   }
168:   return(0);
169: }

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

174:     Not Collective

176: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
177: -   fd - file pointer

179:     Level: intermediate

181:     Fortran Note:
182:     This routine is not supported in Fortran.

184:   Concepts: PetscViewer^file pointer
185:   Concepts: file pointer^getting from PetscViewer

187: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
188:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
189: @*/
190: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
191: {
192:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

195:   *fd = vascii->fd;
196:   return(0);
197: }

199: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
200: {
201:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

204:   *mode = vascii->mode;
205:   return(0);
206: }

208: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
209: {
210:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

213:   vascii->mode = mode;
214:   return(0);
215: }

217: /*
218:    If petsc_history is on, then all Petsc*Printf() results are saved
219:    if the appropriate (usually .petschistory) file.
220: */
221: 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 - obtained with PetscViewerASCIIOpen()
230: -    tabs - number of tabs

232:     Level: developer

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

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

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

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

257: /*@
258:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

260:     Not Collective, meaningful on first processor only.

262:     Input Parameters:
263: .    viewer - obtained with PetscViewerASCIIOpen()
264:     Output Parameters:
265: .    tabs - number of tabs

267:     Level: developer

269:     Fortran Note:
270:     This routine is not supported in Fortran.

272:   Concepts: PetscViewerASCII^formating
273:   Concepts: tab^retrieval

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

287:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
288:   if (iascii && tabs) *tabs = ascii->tab;
289:   return(0);
290: }

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

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

297:     Input Parameters:
298: +    viewer - obtained with PetscViewerASCIIOpen()
299: -    tabs - number of tabs

301:     Level: developer

303:     Fortran Note:
304:     This routine is not supported in Fortran.

306:   Concepts: PetscViewerASCII^formating
307:   Concepts: tab^setting

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

321:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
322:   if (iascii) ascii->tab += tabs;
323:   return(0);
324: }

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

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

331:     Input Parameters:
332: +    viewer - obtained with PetscViewerASCIIOpen()
333: -    tabs - number of tabs

335:     Level: developer

337:     Fortran Note:
338:     This routine is not supported in Fortran.

340:   Concepts: PetscViewerASCII^formating
341:   Concepts: tab^setting

343: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
344:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
345:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
346: @*/
347: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
348: {
349:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
350:   PetscBool         iascii;
351:   PetscErrorCode    ierr;

355:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
356:   if (iascii) ascii->tab -= tabs;
357:   return(0);
358: }

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

363:     Collective on PetscViewer

365:     Input Parameters:
366: .    viewer - obtained with PetscViewerASCIIOpen()

368:     Level: intermediate

370:   Concepts: PetscViewerASCII^formating
371:   Concepts: tab^setting

373: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
374:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
375:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
376: @*/
377: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
378: {
379:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
380:   PetscBool         iascii;
381:   PetscErrorCode    ierr;

385:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
386:   if (iascii) ascii->allowsynchronized++;
387:   return(0);
388: }

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

393:     Collective on PetscViewer

395:     Input Parameters:
396: .    viewer - obtained with PetscViewerASCIIOpen()

398:     Level: intermediate

400:   Concepts: PetscViewerASCII^formating
401:   Concepts: tab^setting

403: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
404:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
405:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
406: @*/
407: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
408: {
409:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
410:   PetscBool         iascii;
411:   PetscErrorCode    ierr;

415:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
416:   if (iascii) {
417:     ascii->allowsynchronized--;
418:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
419:   }
420:   return(0);
421: }

423: /*@
424:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
425:      lines are tabbed.

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

429:     Input Parameters:
430: .    viewer - obtained with PetscViewerASCIIOpen()

432:     Level: developer

434:     Fortran Note:
435:     This routine is not supported in Fortran.

437:   Concepts: PetscViewerASCII^formating
438:   Concepts: tab^setting

440: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
441:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
442:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
443: @*/
444: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
445: {
446:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
447:   PetscBool         iascii;
448:   PetscErrorCode    ierr;

452:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
453:   if (iascii) ascii->tab++;
454:   return(0);
455: }

457: /*@
458:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
459:      lines are tabbed.

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

463:     Input Parameters:
464: .    viewer - obtained with PetscViewerASCIIOpen()

466:     Level: developer

468:     Fortran Note:
469:     This routine is not supported in Fortran.

471:   Concepts: PetscViewerASCII^formating
472:   Concepts: tab^setting

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

486:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
487:   if (iascii) {
488:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
489:     ascii->tab--;
490:   }
491:   return(0);
492: }

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

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

499:     Input Parameters:
500: +    viewer - obtained with PetscViewerASCIIOpen()
501: -    flg - PETSC_TRUE or PETSC_FALSE

503:     Level: developer

505:     Fortran Note:
506:     This routine is not supported in Fortran.

508:   Concepts: PetscViewerASCII^formating
509:   Concepts: tab^setting

511: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
512:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
513:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
514: @*/
515: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
516: {
517:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
518:   PetscBool         iascii;
519:   PetscErrorCode    ierr;

523:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
524:   if (iascii) {
525:     if (flg) ascii->tab = ascii->tab_store;
526:     else {
527:       ascii->tab_store = ascii->tab;
528:       ascii->tab       = 0;
529:     }
530:   }
531:   return(0);
532: }

534: /* ----------------------------------------------------------------------- */


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

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

543:     Input Parameters:
544: +    viewer - obtained with PetscViewerASCIIOpen()
545: -    format - the usual printf() format string

547:     Level: developer

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

553:   Concepts: PetscViewerASCII^printing
554:   Concepts: printing^to file
555:   Concepts: printf

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

574:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
575:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
576:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
577:   if (rank) return(0);

579:   if (ascii->bviewer) { /* pass string up to parent viewer */
580:     char        *string;
581:     va_list     Argp;
582:     size_t      fullLength;

584:     PetscCalloc1(QUEUESTRINGSIZE, &string);
585:     va_start(Argp,format);
586:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
587:     va_end(Argp);
588:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
589:     PetscFree(string);
590:   } else { /* write directly to file */
591:     va_list Argp;
592:     /* flush my own messages that I may have queued up */
593:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
594:     PetscInt    i;
595:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
596:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
597:       previous = next;
598:       next     = next->next;
599:       PetscFree(previous->string);
600:       PetscFree(previous);
601:     }
602:     ascii->petsc_printfqueue       = 0;
603:     ascii->petsc_printfqueuelength = 0;
604:     tab = intab;
605:     while (tab--) {
606:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
607:     }

609:     va_start(Argp,format);
610:     (*PetscVFPrintf)(fd,format,Argp);
611:     err  = fflush(fd);
612:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
613:     if (petsc_history) {
614:       va_start(Argp,format);
615:       tab = intab;
616:       while (tab--) {
617:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
618:       }
619:       (*PetscVFPrintf)(petsc_history,format,Argp);
620:       err  = fflush(petsc_history);
621:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
622:     }
623:     va_end(Argp);
624:   }
625:   return(0);
626: }

628: /*@C
629:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

631:     Collective on PetscViewer

633:   Input Parameters:
634: +  viewer - the PetscViewer; either ASCII or binary
635: -  name - the name of the file it should use

637:     Level: advanced

639: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
640:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

642: @*/
643: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
644: {

650:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,name));
651:   return(0);
652: }

654: /*@C
655:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

657:     Not Collective

659:   Input Parameter:
660: .  viewer - the PetscViewer; either ASCII or binary

662:   Output Parameter:
663: .  name - the name of the file it is using

665:     Level: advanced

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

669: @*/
670: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
671: {

676:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
677:   return(0);
678: }

680: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
681: {
682:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

685:   *name = vascii->filename;
686:   return(0);
687: }

689: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
690: {
691:   PetscErrorCode    ierr;
692:   size_t            len;
693:   char              fname[PETSC_MAX_PATH_LEN],*gz;
694:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
695:   PetscBool         isstderr,isstdout;
696:   PetscMPIInt       rank;

699:   PetscViewerFileClose_ASCII(viewer);
700:   if (!name) return(0);
701:   PetscStrallocpy(name,&vascii->filename);

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

706:   PetscStrstr(vascii->filename,".gz",&gz);
707:   if (gz) {
708:     PetscStrlen(gz,&len);
709:     if (len == 3) {
710:       *gz = 0;
711:       vascii->storecompressed = PETSC_TRUE;
712:     }
713:   }
714:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
715:   if (!rank) {
716:     PetscStrcmp(name,"stderr",&isstderr);
717:     PetscStrcmp(name,"stdout",&isstdout);
718:     /* empty filename means stdout */
719:     if (name[0] == 0)  isstdout = PETSC_TRUE;
720:     if (isstderr)      vascii->fd = PETSC_STDERR;
721:     else if (isstdout) vascii->fd = PETSC_STDOUT;
722:     else {


725:       PetscFixFilename(name,fname);
726:       switch (vascii->mode) {
727:       case FILE_MODE_READ:
728:         vascii->fd = fopen(fname,"r");
729:         break;
730:       case FILE_MODE_WRITE:
731:         vascii->fd = fopen(fname,"w");
732:         break;
733:       case FILE_MODE_APPEND:
734:         vascii->fd = fopen(fname,"a");
735:         break;
736:       case FILE_MODE_UPDATE:
737:         vascii->fd = fopen(fname,"r+");
738:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
739:         break;
740:       case FILE_MODE_APPEND_UPDATE:
741:         /* I really want a file which is opened at the end for updating,
742:            not a+, which opens at the beginning, but makes writes at the end.
743:         */
744:         vascii->fd = fopen(fname,"r+");
745:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
746:         else {
747:           fseek(vascii->fd, 0, SEEK_END);
748:         }
749:         break;
750:       default:
751:         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
752:       }
753:       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
754:     }
755:   }
756: #if defined(PETSC_USE_LOG)
757:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
758: #endif
759:   return(0);
760: }

762: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
763: {
764:   PetscMPIInt       rank;
765:   PetscErrorCode    ierr;
766:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

769:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
770:   PetscViewerASCIIPushSynchronized(viewer);
771:   PetscViewerCreate(subcomm,outviewer);
772:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
773:   PetscViewerASCIIPushSynchronized(*outviewer);
774:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
775:   ovascii->fd  = vascii->fd;
776:   ovascii->tab = vascii->tab;
777:   ovascii->closefile = PETSC_FALSE;

779:   vascii->sviewer = *outviewer;

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

783:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
784:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
785:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
786:   return(0);
787: }

789: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
790: {
791:   PetscErrorCode    ierr;
792:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

798:   ascii->sviewer             = 0;
799:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
800:   PetscViewerDestroy(outviewer);
801:   return(0);
802: }

804: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
805: {
806:   PetscErrorCode    ierr;
807:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

810:   if (ascii->filename) {
811:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
812:   }
813:   return(0);
814: }

816: /*MC
817:    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file


820: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
821:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
822:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

824:   Level: beginner

826: M*/
827: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
828: {
829:   PetscViewer_ASCII *vascii;
830:   PetscErrorCode    ierr;

833:   PetscNewLog(viewer,&vascii);
834:   viewer->data = (void*)vascii;

836:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
837:   viewer->ops->flush            = PetscViewerFlush_ASCII;
838:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
839:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
840:   viewer->ops->view             = PetscViewerView_ASCII;
841:   viewer->ops->read             = PetscViewerASCIIRead;

843:   /* defaults to stdout unless set with PetscViewerFileSetName() */
844:   vascii->fd        = PETSC_STDOUT;
845:   vascii->mode      = FILE_MODE_WRITE;
846:   vascii->bviewer   = 0;
847:   vascii->subviewer = 0;
848:   vascii->sviewer   = 0;
849:   vascii->tab       = 0;
850:   vascii->tab_store = 0;
851:   vascii->filename  = 0;
852:   vascii->closefile = PETSC_TRUE;

854:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
855:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
856:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
857:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
858:   return(0);
859: }

861: /*@C
862:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
863:     several processors.  Output of the first processor is followed by that of the
864:     second, etc.

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

868:     Input Parameters:
869: +   viewer - the ASCII PetscViewer
870: -   format - the usual printf() format string

872:     Level: intermediate

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

876:     Fortran Note:
877:       Can only print a single character* string

879: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
880:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
881:           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()

883: @*/
884: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
885: {
886:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
887:   PetscErrorCode    ierr;
888:   PetscMPIInt       rank;
889:   PetscInt          tab = vascii->tab;
890:   MPI_Comm          comm;
891:   FILE              *fp;
892:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
893:   int               err;

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

902:   PetscObjectGetComm((PetscObject)viewer,&comm);
903:   MPI_Comm_rank(comm,&rank);

905:   if (vascii->bviewer) {
906:     hasbviewer = PETSC_TRUE;
907:     if (!rank) {
908:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
909:       PetscObjectGetComm((PetscObject)viewer,&comm);
910:       MPI_Comm_rank(comm,&rank);
911:     }
912:   }

914:   fp   = vascii->fd;

916:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
917:     va_list Argp;
918:     /* flush my own messages that I may have queued up */
919:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
920:     PetscInt    i;
921:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
922:       PetscFPrintf(comm,fp,"%s",next->string);
923:       previous = next;
924:       next     = next->next;
925:       PetscFree(previous->string);
926:       PetscFree(previous);
927:     }
928:     vascii->petsc_printfqueue       = 0;
929:     vascii->petsc_printfqueuelength = 0;

931:     while (tab--) {
932:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
933:     }

935:     va_start(Argp,format);
936:     (*PetscVFPrintf)(fp,format,Argp);
937:     err  = fflush(fp);
938:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
939:     if (petsc_history) {
940:       va_start(Argp,format);
941:       (*PetscVFPrintf)(petsc_history,format,Argp);
942:       err  = fflush(petsc_history);
943:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
944:     }
945:     va_end(Argp);
946:   } else { /* other processors add to queue */
947:     char        *string;
948:     va_list     Argp;
949:     size_t      fullLength;
950:     PrintfQueue next;

952:     PetscNew(&next);
953:     if (vascii->petsc_printfqueue) {
954:       vascii->petsc_printfqueue->next = next;
955:       vascii->petsc_printfqueue       = next;
956:     } else {
957:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
958:     }
959:     vascii->petsc_printfqueuelength++;
960:     next->size = QUEUESTRINGSIZE;
961:     PetscMalloc1(next->size, &next->string);
962:     PetscMemzero(next->string,next->size);
963:     string     = next->string;
964:     tab       *= 2;
965:     while (tab--) {
966:       *string++ = ' ';
967:     }
968:     va_start(Argp,format);
969:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
970:     va_end(Argp);
971:   }
972:   return(0);
973: }

975: /*@C
976:    PetscViewerASCIIRead - Reads from am ASCII file

978:    Collective on MPI_Comm

980:    Input Parameters:
981: +  viewer - the ascii viewer
982: .  data - location to write the data
983: .  num - number of items of data to read
984: -  datatype - type of data to read

986:    Output Parameters:
987: .  count - number of items of data actually read, or NULL

989:    Level: beginner

991:    Concepts: ascii files

993: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
994:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
995:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
996: @*/
997: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
998: {
999:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1000:   FILE              *fd = vascii->fd;
1001:   PetscInt           i;
1002:   int                ret = 0;

1006:   for (i=0; i<num; i++) {
1007:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1008:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1009:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1010:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1011:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1012:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1013:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1014:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1015:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1016:   }
1017:   if (count) *count = i;
1018:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1019:   return(0);
1020: }