Actual source code: filev.c


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

  4: #define QUEUESTRINGSIZE 8192

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

 13:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
 14:   if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
 15:     if (vascii->fd && vascii->closefile) {
 16:       err = fclose(vascii->fd);
 18:     }
 19:     if (vascii->storecompressed) {
 20:       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
 21:       FILE *fp;
 22:       PetscStrncpy(par,"gzip ",sizeof(par));
 23:       PetscStrlcat(par,vascii->filename,sizeof(par));
 24: #if defined(PETSC_HAVE_POPEN)
 25:       PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);
 27:       PetscPClose(PETSC_COMM_SELF,fp);
 28: #else
 29:       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
 30: #endif
 31:     }
 32:   }
 33:   PetscFree(vascii->filename);
 34:   return 0;
 35: }

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

 45:   PetscViewerFileClose_ASCII(viewer);
 46:   PetscFree(vascii);

 48:   /* remove the viewer from the list in the MPI Communicator */
 49:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
 50:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
 51:   }

 53:   MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
 54:   if (flg) {
 55:     if (vlink && vlink->viewer == viewer) {
 56:       if (vlink->next) {
 57:         MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
 58:       } else {
 59:         MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);
 60:       }
 61:       PetscFree(vlink);
 62:     } else {
 63:       while (vlink && vlink->next) {
 64:         if (vlink->next->viewer == viewer) {
 65:           PetscViewerLink *nv = vlink->next;
 66:           vlink->next = vlink->next->next;
 67:           PetscFree(nv);
 68:         }
 69:         vlink = vlink->next;
 70:       }
 71:     }
 72:   }

 74:   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
 75:     PetscViewer aviewer;
 76:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
 77:     if (flg && aviewer == viewer) {
 78:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);
 79:     }
 80:   }
 81:   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
 82:     PetscViewer aviewer;
 83:     MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);
 84:     if (flg && aviewer == viewer) {
 85:       MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);
 86:     }
 87:   }
 88:   return 0;
 89: }

 91: PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
 92: {
 93:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

 95:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
 96:   return 0;
 97: }

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

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

112:   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
113:     err = fflush(vascii->fd);
115:   }

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

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

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

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

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

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

183:     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer

185:     Input Parameter:
186: .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()

188:     Output Parameter:
189: .    fd - file pointer

191:     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer

193:     Level: intermediate

195:     Fortran Note:
196:     This routine is not supported in Fortran.

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

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

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

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

217: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
218: {
219:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

221:   vascii->mode = mode;
222:   return 0;
223: }

225: /*
226:    If petsc_history is on, then all Petsc*Printf() results are saved
227:    if the appropriate (usually .petschistory) file.
228: */
229: PETSC_INTERN FILE *petsc_history;

231: /*@
232:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

236:     Input Parameters:
237: +    viewer - obtained with PetscViewerASCIIOpen()
238: -    tabs - number of tabs

240:     Level: developer

242:     Fortran Note:
243:     This routine is not supported in Fortran.

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

255:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
256:   if (iascii) ascii->tab = tabs;
257:   return 0;
258: }

260: /*@
261:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

263:     Not Collective, meaningful on first processor only.

265:     Input Parameters:
266: .    viewer - obtained with PetscViewerASCIIOpen()

268:     Output Parameters:
269: .    tabs - number of tabs

271:     Level: developer

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

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

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

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

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

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

300:     Level: developer

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

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

315:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
316:   if (iascii) ascii->tab += tabs;
317:   return 0;
318: }

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

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

325:     Input Parameters:
326: +    viewer - obtained with PetscViewerASCIIOpen()
327: -    tabs - number of tabs

329:     Level: developer

331:     Fortran Note:
332:     This routine is not supported in Fortran.

334: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
335:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
336:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
337: @*/
338: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
339: {
340:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
341:   PetscBool         iascii;

344:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
345:   if (iascii) ascii->tab -= tabs;
346:   return 0;
347: }

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

352:     Collective on PetscViewer

354:     Input Parameters:
355: .    viewer - obtained with PetscViewerASCIIOpen()

357:     Level: intermediate

359:     Notes:
360:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

362: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
363:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
364:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
365: @*/
366: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
367: {
368:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
369:   PetscBool         iascii;

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

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

381:     Collective on PetscViewer

383:     Input Parameters:
384: .    viewer - obtained with PetscViewerASCIIOpen()

386:     Level: intermediate

388:     Notes:
389:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

391: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
392:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
393:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
394: @*/
395: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
396: {
397:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
398:   PetscBool         iascii;

402:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
403:   if (iascii) {
404:     ascii->allowsynchronized--;
406:   }
407:   return 0;
408: }

410: /*@C
411:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
412:      lines are tabbed.

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

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

419:     Level: developer

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

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

434:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
435:   if (iascii) ascii->tab++;
436:   return 0;
437: }

439: /*@C
440:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
441:      lines are tabbed.

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

445:     Input Parameters:
446: .    viewer - obtained with PetscViewerASCIIOpen()

448:     Level: developer

450:     Fortran Note:
451:     This routine is not supported in Fortran.

453: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
454:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
455:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
456: @*/
457: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
458: {
459:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
460:   PetscBool         iascii;

463:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
464:   if (iascii) {
466:     ascii->tab--;
467:   }
468:   return 0;
469: }

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

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

476:     Input Parameters:
477: +    viewer - obtained with PetscViewerASCIIOpen()
478: -    flg - PETSC_TRUE or PETSC_FALSE

480:     Level: developer

482:     Fortran Note:
483:     This routine is not supported in Fortran.

485: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
486:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
487:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
488: @*/
489: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
490: {
491:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
492:   PetscBool         iascii;

495:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
496:   if (iascii) {
497:     if (flg) ascii->tab = ascii->tab_store;
498:     else {
499:       ascii->tab_store = ascii->tab;
500:       ascii->tab       = 0;
501:     }
502:   }
503:   return 0;
504: }

506: /* ----------------------------------------------------------------------- */

508: /*@C
509:     PetscViewerASCIIPrintf - Prints to a file, only from the first
510:     processor in the PetscViewer

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

514:     Input Parameters:
515: +    viewer - obtained with PetscViewerASCIIOpen()
516: -    format - the usual printf() format string

518:     Level: developer

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

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

540:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
542:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
543:   if (rank) return 0;

545:   if (ascii->bviewer) { /* pass string up to parent viewer */
546:     char        *string;
547:     va_list     Argp;
548:     size_t      fullLength;

550:     PetscCalloc1(QUEUESTRINGSIZE, &string);
551:     va_start(Argp,format);
552:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
553:     va_end(Argp);
554:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
555:     PetscFree(string);
556:   } else { /* write directly to file */
557:     va_list Argp;
558:     /* flush my own messages that I may have queued up */
559:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
560:     PetscInt    i;
561:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
562:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
563:       previous = next;
564:       next     = next->next;
565:       PetscFree(previous->string);
566:       PetscFree(previous);
567:     }
568:     ascii->petsc_printfqueue       = NULL;
569:     ascii->petsc_printfqueuelength = 0;
570:     tab = intab;
571:     while (tab--) {
572:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
573:     }

575:     va_start(Argp,format);
576:     (*PetscVFPrintf)(fd,format,Argp);
577:     err  = fflush(fd);
579:     if (petsc_history) {
580:       va_start(Argp,format);
581:       tab = intab;
582:       while (tab--) {
583:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
584:       }
585:       (*PetscVFPrintf)(petsc_history,format,Argp);
586:       err  = fflush(petsc_history);
588:     }
589:     va_end(Argp);
590:   }
591:   return 0;
592: }

594: /*@C
595:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

597:     Collective on PetscViewer

599:   Input Parameters:
600: +  viewer - the PetscViewer; either ASCII or binary
601: -  name - the name of the file it should use

603:     Level: advanced

605: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
606:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

608: @*/
609: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
610: {
611:   char           filename[PETSC_MAX_PATH_LEN];

615:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
616:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
617:   return 0;
618: }

620: /*@C
621:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

623:     Not Collective

625:   Input Parameter:
626: .  viewer - the PetscViewer; either ASCII or binary

628:   Output Parameter:
629: .  name - the name of the file it is using

631:     Level: advanced

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

635: @*/
636: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
637: {
640:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
641:   return 0;
642: }

644: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
645: {
646:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

648:   *name = vascii->filename;
649:   return 0;
650: }

652: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
653: {
654:   size_t            len;
655:   char              fname[PETSC_MAX_PATH_LEN],*gz;
656:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
657:   PetscBool         isstderr,isstdout;
658:   PetscMPIInt       rank;

660:   PetscViewerFileClose_ASCII(viewer);
661:   if (!name) return 0;
662:   PetscStrallocpy(name,&vascii->filename);

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

667:   PetscStrstr(vascii->filename,".gz",&gz);
668:   if (gz) {
669:     PetscStrlen(gz,&len);
670:     if (len == 3) {
672:       *gz = 0;
673:       vascii->storecompressed = PETSC_TRUE;
674:     }
675:   }
676:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
677:   if (rank == 0) {
678:     PetscStrcmp(name,"stderr",&isstderr);
679:     PetscStrcmp(name,"stdout",&isstdout);
680:     /* empty filename means stdout */
681:     if (name[0] == 0)  isstdout = PETSC_TRUE;
682:     if (isstderr)      vascii->fd = PETSC_STDERR;
683:     else if (isstdout) vascii->fd = PETSC_STDOUT;
684:     else {

686:       PetscFixFilename(name,fname);
687:       switch (vascii->mode) {
688:       case FILE_MODE_READ:
689:         vascii->fd = fopen(fname,"r");
690:         break;
691:       case FILE_MODE_WRITE:
692:         vascii->fd = fopen(fname,"w");
693:         break;
694:       case FILE_MODE_APPEND:
695:         vascii->fd = fopen(fname,"a");
696:         break;
697:       case FILE_MODE_UPDATE:
698:         vascii->fd = fopen(fname,"r+");
699:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
700:         break;
701:       case FILE_MODE_APPEND_UPDATE:
702:         /* I really want a file which is opened at the end for updating,
703:            not a+, which opens at the beginning, but makes writes at the end.
704:         */
705:         vascii->fd = fopen(fname,"r+");
706:         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
707:         else {
708:           fseek(vascii->fd, 0, SEEK_END);
709:         }
710:         break;
711:       default:
712:         SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
713:       }
715:     }
716:   }
717: #if defined(PETSC_USE_LOG)
718:   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
719: #endif
720:   return 0;
721: }

723: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
724: {
725:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

727:   PetscViewerASCIIPushSynchronized(viewer);
729:   /*
730:      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
731:      because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
732:      (since the count never gets to zero) in some examples this displays information that otherwise would be lost

734:      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
735:      PCView_GASM().
736:   */
737:   PetscViewerASCIIPushSynchronized(viewer);
738:   PetscViewerCreate(subcomm,outviewer);
739:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
740:   PetscViewerASCIIPushSynchronized(*outviewer);
741:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
742:   ovascii->fd  = vascii->fd;
743:   ovascii->tab = vascii->tab;
744:   ovascii->closefile = PETSC_FALSE;

746:   vascii->sviewer = *outviewer;
747:   (*outviewer)->format  = viewer->format;
748:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
749:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
750:   return 0;
751: }

753: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
754: {
755:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;


760:   PetscViewerASCIIPopSynchronized(*outviewer);
761:   ascii->sviewer             = NULL;
762:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
763:   PetscViewerDestroy(outviewer);
764:   PetscViewerASCIIPopSynchronized(viewer);
765:   return 0;
766: }

768: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
769: {
770:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

772:   if (ascii->filename) {
773:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
774:   }
775:   return 0;
776: }

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

781: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
782:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
783:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

785:   Level: beginner

787: M*/
788: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
789: {
790:   PetscViewer_ASCII *vascii;

792:   PetscNewLog(viewer,&vascii);
793:   viewer->data = (void*)vascii;

795:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
796:   viewer->ops->flush            = PetscViewerFlush_ASCII;
797:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
798:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
799:   viewer->ops->view             = PetscViewerView_ASCII;
800:   viewer->ops->read             = PetscViewerASCIIRead;

802:   /* defaults to stdout unless set with PetscViewerFileSetName() */
803:   vascii->fd        = PETSC_STDOUT;
804:   vascii->mode      = FILE_MODE_WRITE;
805:   vascii->bviewer   = NULL;
806:   vascii->subviewer = NULL;
807:   vascii->sviewer   = NULL;
808:   vascii->tab       = 0;
809:   vascii->tab_store = 0;
810:   vascii->filename  = NULL;
811:   vascii->closefile = PETSC_TRUE;

813:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
814:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
815:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
816:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
817:   return 0;
818: }

820: /*@C
821:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
822:     several processors.  Output of the first processor is followed by that of the
823:     second, etc.

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

827:     Input Parameters:
828: +   viewer - the ASCII PetscViewer
829: -   format - the usual printf() format string

831:     Level: intermediate

833:     Notes:
834:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
835:     Then you can do multiple independent calls to this routine.
836:     The actual synchronized print is then done using PetscViewerFlush().
837:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
838:     to conclude the "synchronized session".
839:     So the typical calling sequence looks like
840: $ PetscViewerASCIIPushSynchronized(viewer);
841: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
842: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
843: $ ...
844: $ PetscViewerFlush(viewer);
845: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
846: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
847: $ ...
848: $ PetscViewerFlush(viewer);
849: $ PetscViewerASCIIPopSynchronized(viewer);

851:     Fortran Note:
852:       Can only print a single character* string

854: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
855:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
856:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
857: @*/
858: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
859: {
860:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
861:   PetscMPIInt       rank;
862:   PetscInt          tab = vascii->tab;
863:   MPI_Comm          comm;
864:   FILE              *fp;
865:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
866:   int               err;

870:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);

874:   PetscObjectGetComm((PetscObject)viewer,&comm);
875:   MPI_Comm_rank(comm,&rank);

877:   if (vascii->bviewer) {
878:     hasbviewer = PETSC_TRUE;
879:     if (rank == 0) {
880:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
881:       PetscObjectGetComm((PetscObject)viewer,&comm);
882:       MPI_Comm_rank(comm,&rank);
883:     }
884:   }

886:   fp   = vascii->fd;

888:   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
889:     va_list Argp;
890:     /* flush my own messages that I may have queued up */
891:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
892:     PetscInt    i;
893:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
894:       PetscFPrintf(comm,fp,"%s",next->string);
895:       previous = next;
896:       next     = next->next;
897:       PetscFree(previous->string);
898:       PetscFree(previous);
899:     }
900:     vascii->petsc_printfqueue       = NULL;
901:     vascii->petsc_printfqueuelength = 0;

903:     while (tab--) {
904:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
905:     }

907:     va_start(Argp,format);
908:     (*PetscVFPrintf)(fp,format,Argp);
909:     err  = fflush(fp);
911:     if (petsc_history) {
912:       va_start(Argp,format);
913:       (*PetscVFPrintf)(petsc_history,format,Argp);
914:       err  = fflush(petsc_history);
916:     }
917:     va_end(Argp);
918:   } else { /* other processors add to queue */
919:     char        *string;
920:     va_list     Argp;
921:     size_t      fullLength;
922:     PrintfQueue next;

924:     PetscNew(&next);
925:     if (vascii->petsc_printfqueue) {
926:       vascii->petsc_printfqueue->next = next;
927:       vascii->petsc_printfqueue       = next;
928:     } else {
929:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
930:     }
931:     vascii->petsc_printfqueuelength++;
932:     next->size = QUEUESTRINGSIZE;
933:     PetscCalloc1(next->size, &next->string);
934:     string     = next->string;
935:     tab       *= 2;
936:     while (tab--) {
937:       *string++ = ' ';
938:     }
939:     va_start(Argp,format);
940:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
941:     va_end(Argp);
942:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
943:       PetscFree(next->string);
944:       next->size = fullLength + 2*vascii->tab;
945:       PetscCalloc1(next->size, &next->string);
946:       string     = next->string;
947:       tab        = 2*vascii->tab;
948:       while (tab--) {
949:         *string++ = ' ';
950:       }
951:       va_start(Argp,format);
952:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
953:       va_end(Argp);
954:     }
955:   }
956:   return 0;
957: }

959: /*@C
960:    PetscViewerASCIIRead - Reads from a ASCII file

962:    Only process 0 in the PetscViewer may call this

964:    Input Parameters:
965: +  viewer - the ascii viewer
966: .  data - location to write the data
967: .  num - number of items of data to read
968: -  datatype - type of data to read

970:    Output Parameters:
971: .  count - number of items of data actually read, or NULL

973:    Level: beginner

975: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
976:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
977:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
978: @*/
979: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
980: {
981:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
982:   FILE              *fd = vascii->fd;
983:   PetscInt           i;
984:   int                ret = 0;
985:   PetscMPIInt        rank;

988:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
990:   for (i=0; i<num; i++) {
991:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
992:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
993:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
994:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
995:     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
996:     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
997:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
998:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
999: #if defined(PETSC_USE_REAL___FLOAT128)
1000:     else if (dtype == PETSC___FLOAT128) {
1001:       double tmp;
1002:       ret = fscanf(fd, "%lg", &tmp);
1003:       ((__float128*)data)[i] = tmp;
1004:     }
1005: #endif
1006:     else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1008:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1009:   }
1010:   if (count) *count = i;
1012:   return 0;
1013: }