Actual source code: filev.c

petsc-master 2017-09-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: /*@C
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: /*@C
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:       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
711:       *gz = 0;
712:       vascii->storecompressed = PETSC_TRUE;
713:     }
714:   }
715:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
716:   if (!rank) {
717:     PetscStrcmp(name,"stderr",&isstderr);
718:     PetscStrcmp(name,"stdout",&isstdout);
719:     /* empty filename means stdout */
720:     if (name[0] == 0)  isstdout = PETSC_TRUE;
721:     if (isstderr)      vascii->fd = PETSC_STDERR;
722:     else if (isstdout) vascii->fd = PETSC_STDOUT;
723:     else {


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

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

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

780:   vascii->sviewer = *outviewer;

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

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

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

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

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

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

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

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


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

825:   Level: beginner

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

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

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

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

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

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

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

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

873:     Level: intermediate

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

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

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

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

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

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

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

915:   fp   = vascii->fd;

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

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

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

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

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

979:    Collective on MPI_Comm

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

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

990:    Level: beginner

992:    Concepts: ascii files

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

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