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:   PetscErrorCode    ierr;
  9:   PetscMPIInt       rank;
 10:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
 11:   int               err;

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

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

 48:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
 49:   PetscViewerFileClose_ASCII(viewer);
 50:   PetscFree(vascii);

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

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

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

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

101:   PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);
102:   return(0);
103: }

105: PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
106: {
107:   PetscErrorCode    ierr;
108:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
109:   int               err;
110:   MPI_Comm          comm;
111:   PetscMPIInt       rank,size;
112:   FILE              *fd = vascii->fd;

115:   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
116:   PetscObjectGetComm((PetscObject)viewer,&comm);
117:   MPI_Comm_rank(comm,&rank);
118:   MPI_Comm_size(comm,&size);

120:   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
121:     err = fflush(vascii->fd);
122:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
123:   }

125:   if (vascii->allowsynchronized) {
126:     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
127:     char          *message;
128:     MPI_Status    status;

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

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

156:           MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);
157:           PetscMalloc1(size, &message);
158:           MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);
159:           if (!vascii->bviewer) {
160:             PetscFPrintf(comm,fd,"%s",message);
161:           } else {
162:             PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);
163:           }
164:           PetscFree(message);
165:         }
166:       }
167:     } else { /* other processors send queue to processor 0 */
168:       PrintfQueue next = vascii->petsc_printfqueuebase,previous;

170:       MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);
171:       MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);
172:       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
173:         MPI_Send(&next->size,1,MPI_INT,0,tag,comm);
174:         MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);
175:         previous = next;
176:         next     = next->next;
177:         PetscFree(previous->string);
178:         PetscFree(previous);
179:       }
180:       vascii->petsc_printfqueue       = NULL;
181:       vascii->petsc_printfqueuelength = 0;
182:     }
183:     PetscCommDestroy(&comm);
184:   }
185:   return(0);
186: }

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

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

193:     Input Parameter:
194: .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()

196:     Output Parameter:
197: .    fd - file pointer

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

201:     Level: intermediate

203:     Fortran Note:
204:     This routine is not supported in Fortran.

206: .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
207:           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
208: @*/
209: PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
210: {
211:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

214:   *fd = vascii->fd;
215:   return(0);
216: }

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

223:   *mode = vascii->mode;
224:   return(0);
225: }

227: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
228: {
229:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

232:   vascii->mode = mode;
233:   return(0);
234: }

236: /*
237:    If petsc_history is on, then all Petsc*Printf() results are saved
238:    if the appropriate (usually .petschistory) file.
239: */
240: PETSC_INTERN FILE *petsc_history;

242: /*@
243:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

247:     Input Parameters:
248: +    viewer - obtained with PetscViewerASCIIOpen()
249: -    tabs - number of tabs

251:     Level: developer

253:     Fortran Note:
254:     This routine is not supported in Fortran.

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

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

273: /*@
274:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

276:     Not Collective, meaningful on first processor only.

278:     Input Parameters:
279: .    viewer - obtained with PetscViewerASCIIOpen()

281:     Output Parameters:
282: .    tabs - number of tabs

284:     Level: developer

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

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

301:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
302:   if (iascii && tabs) *tabs = ascii->tab;
303:   return(0);
304: }

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

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

311:     Input Parameters:
312: +    viewer - obtained with PetscViewerASCIIOpen()
313: -    tabs - number of tabs

315:     Level: developer

317:     Fortran Note:
318:     This routine is not supported in Fortran.

320: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
321:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
322:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
323: @*/
324: PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
325: {
326:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
327:   PetscBool         iascii;
328:   PetscErrorCode    ierr;

332:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
333:   if (iascii) ascii->tab += tabs;
334:   return(0);
335: }

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

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

342:     Input Parameters:
343: +    viewer - obtained with PetscViewerASCIIOpen()
344: -    tabs - number of tabs

346:     Level: developer

348:     Fortran Note:
349:     This routine is not supported in Fortran.

351: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
352:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
353:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
354: @*/
355: PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
356: {
357:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
358:   PetscBool         iascii;
359:   PetscErrorCode    ierr;

363:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
364:   if (iascii) ascii->tab -= tabs;
365:   return(0);
366: }

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

371:     Collective on PetscViewer

373:     Input Parameters:
374: .    viewer - obtained with PetscViewerASCIIOpen()

376:     Level: intermediate

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

381: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
382:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
383:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
384: @*/
385: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
386: {
387:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
388:   PetscBool         iascii;
389:   PetscErrorCode    ierr;

393:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
394:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
395:   if (iascii) ascii->allowsynchronized++;
396:   return(0);
397: }

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

402:     Collective on PetscViewer

404:     Input Parameters:
405: .    viewer - obtained with PetscViewerASCIIOpen()

407:     Level: intermediate

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

412: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
413:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
414:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
415: @*/
416: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
417: {
418:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
419:   PetscBool         iascii;
420:   PetscErrorCode    ierr;

424:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
425:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
426:   if (iascii) {
427:     ascii->allowsynchronized--;
428:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
429:   }
430:   return(0);
431: }

433: /*@C
434:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
435:      lines are tabbed.

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

439:     Input Parameters:
440: .    viewer - obtained with PetscViewerASCIIOpen()

442:     Level: developer

444:     Fortran Note:
445:     This routine is not supported in Fortran.

447: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
448:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
449:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
450: @*/
451: PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
452: {
453:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
454:   PetscBool         iascii;
455:   PetscErrorCode    ierr;

459:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
460:   if (iascii) ascii->tab++;
461:   return(0);
462: }

464: /*@C
465:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
466:      lines are tabbed.

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

470:     Input Parameters:
471: .    viewer - obtained with PetscViewerASCIIOpen()

473:     Level: developer

475:     Fortran Note:
476:     This routine is not supported in Fortran.

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

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

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

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

503:     Input Parameters:
504: +    viewer - obtained with PetscViewerASCIIOpen()
505: -    flg - PETSC_TRUE or PETSC_FALSE

507:     Level: developer

509:     Fortran Note:
510:     This routine is not supported in Fortran.

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

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

535: /* ----------------------------------------------------------------------- */

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

569:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
571:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
572:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
573:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
574:   if (rank) return(0);

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

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

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

625: /*@C
626:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

628:     Collective on PetscViewer

630:   Input Parameters:
631: +  viewer - the PetscViewer; either ASCII or binary
632: -  name - the name of the file it should use

634:     Level: advanced

636: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
637:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

639: @*/
640: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
641: {
643:   char           filename[PETSC_MAX_PATH_LEN];

648:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
649:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
650:   return(0);
651: }

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

656:     Not Collective

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

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

664:     Level: advanced

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

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

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 == 0) {
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 {

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(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[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:   PetscErrorCode    ierr;
765:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

768:   PetscViewerASCIIPushSynchronized(viewer);
769:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
770:   /*
771:      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
772:      because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
773:      (since the count never gets to zero) in some examples this displays information that otherwise would be lost

775:      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
776:      PCView_GASM().
777:   */
778:   PetscViewerASCIIPushSynchronized(viewer);
779:   PetscViewerCreate(subcomm,outviewer);
780:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
781:   PetscViewerASCIIPushSynchronized(*outviewer);
782:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
783:   ovascii->fd  = vascii->fd;
784:   ovascii->tab = vascii->tab;
785:   ovascii->closefile = PETSC_FALSE;

787:   vascii->sviewer = *outviewer;
788:   (*outviewer)->format  = viewer->format;
789:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
790:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
791:   return(0);
792: }

794: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
795: {
796:   PetscErrorCode    ierr;
797:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

803:   PetscViewerASCIIPopSynchronized(*outviewer);
804:   ascii->sviewer             = NULL;
805:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
806:   PetscViewerDestroy(outviewer);
807:   PetscViewerASCIIPopSynchronized(viewer);
808:   return(0);
809: }

811: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
812: {
813:   PetscErrorCode    ierr;
814:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

817:   if (ascii->filename) {
818:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
819:   }
820:   return(0);
821: }

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

826: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
827:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
828:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

830:   Level: beginner

832: M*/
833: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
834: {
835:   PetscViewer_ASCII *vascii;
836:   PetscErrorCode    ierr;

839:   PetscNewLog(viewer,&vascii);
840:   viewer->data = (void*)vascii;

842:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
843:   viewer->ops->flush            = PetscViewerFlush_ASCII;
844:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
845:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
846:   viewer->ops->view             = PetscViewerView_ASCII;
847:   viewer->ops->read             = PetscViewerASCIIRead;

849:   /* defaults to stdout unless set with PetscViewerFileSetName() */
850:   vascii->fd        = PETSC_STDOUT;
851:   vascii->mode      = FILE_MODE_WRITE;
852:   vascii->bviewer   = NULL;
853:   vascii->subviewer = NULL;
854:   vascii->sviewer   = NULL;
855:   vascii->tab       = 0;
856:   vascii->tab_store = 0;
857:   vascii->filename  = NULL;
858:   vascii->closefile = PETSC_TRUE;

860:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
861:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
862:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
863:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
864:   return(0);
865: }

867: /*@C
868:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
869:     several processors.  Output of the first processor is followed by that of the
870:     second, etc.

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

874:     Input Parameters:
875: +   viewer - the ASCII PetscViewer
876: -   format - the usual printf() format string

878:     Level: intermediate

880:     Notes:
881:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
882:     Then you can do multiple independent calls to this routine.
883:     The actual synchronized print is then done using PetscViewerFlush().
884:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
885:     to conclude the "synchronized session".
886:     So the typical calling sequence looks like
887: $ PetscViewerASCIIPushSynchronized(viewer);
888: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
889: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
890: $ ...
891: $ PetscViewerFlush(viewer);
892: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
893: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
894: $ ...
895: $ PetscViewerFlush(viewer);
896: $ PetscViewerASCIIPopSynchronized(viewer);

898:     Fortran Note:
899:       Can only print a single character* string

901: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
902:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
903:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
904: @*/
905: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
906: {
907:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
908:   PetscErrorCode    ierr;
909:   PetscMPIInt       rank;
910:   PetscInt          tab = vascii->tab;
911:   MPI_Comm          comm;
912:   FILE              *fp;
913:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
914:   int               err;

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

923:   PetscObjectGetComm((PetscObject)viewer,&comm);
924:   MPI_Comm_rank(comm,&rank);

926:   if (vascii->bviewer) {
927:     hasbviewer = PETSC_TRUE;
928:     if (rank == 0) {
929:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
930:       PetscObjectGetComm((PetscObject)viewer,&comm);
931:       MPI_Comm_rank(comm,&rank);
932:     }
933:   }

935:   fp   = vascii->fd;

937:   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
938:     va_list Argp;
939:     /* flush my own messages that I may have queued up */
940:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
941:     PetscInt    i;
942:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
943:       PetscFPrintf(comm,fp,"%s",next->string);
944:       previous = next;
945:       next     = next->next;
946:       PetscFree(previous->string);
947:       PetscFree(previous);
948:     }
949:     vascii->petsc_printfqueue       = NULL;
950:     vascii->petsc_printfqueuelength = 0;

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

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

973:     PetscNew(&next);
974:     if (vascii->petsc_printfqueue) {
975:       vascii->petsc_printfqueue->next = next;
976:       vascii->petsc_printfqueue       = next;
977:     } else {
978:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
979:     }
980:     vascii->petsc_printfqueuelength++;
981:     next->size = QUEUESTRINGSIZE;
982:     PetscCalloc1(next->size, &next->string);
983:     string     = next->string;
984:     tab       *= 2;
985:     while (tab--) {
986:       *string++ = ' ';
987:     }
988:     va_start(Argp,format);
989:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
990:     va_end(Argp);
991:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
992:       PetscFree(next->string);
993:       next->size = fullLength + 2*vascii->tab;
994:       PetscCalloc1(next->size, &next->string);
995:       string     = next->string;
996:       tab        = 2*vascii->tab;
997:       while (tab--) {
998:         *string++ = ' ';
999:       }
1000:       va_start(Argp,format);
1001:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1002:       va_end(Argp);
1003:     }
1004:   }
1005:   return(0);
1006: }

1008: /*@C
1009:    PetscViewerASCIIRead - Reads from a ASCII file

1011:    Only process 0 in the PetscViewer may call this

1013:    Input Parameters:
1014: +  viewer - the ascii viewer
1015: .  data - location to write the data
1016: .  num - number of items of data to read
1017: -  datatype - type of data to read

1019:    Output Parameters:
1020: .  count - number of items of data actually read, or NULL

1022:    Level: beginner

1024: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1025:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1026:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1027: @*/
1028: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1029: {
1030:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1031:   FILE              *fd = vascii->fd;
1032:   PetscInt           i;
1033:   int                ret = 0;
1034:   PetscMPIInt        rank;
1035:   PetscErrorCode     ierr;

1039:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1040:   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1041:   for (i=0; i<num; i++) {
1042:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1043:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1044:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1045:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1046:     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1047:     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1048:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1049:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1050: #if defined(PETSC_USE_REAL___FLOAT128)
1051:     else if (dtype == PETSC___FLOAT128) {
1052:       double tmp;
1053:       ret = fscanf(fd, "%lg", &tmp);
1054:       ((__float128*)data)[i] = tmp;
1055:     }
1056: #endif
1057:     else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1058:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1059:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1060:   }
1061:   if (count) *count = i;
1062:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1063:   return(0);
1064: }