Actual source code: filev.c

petsc-3.11.4 2019-09-28
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:       PetscStrncpy(par,"gzip ",sizeof(par));
 24:       PetscStrlcat(par,vascii->filename,sizeof(par));
 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);
 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_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
 54:   }

 56:   MPI_Comm_get_attr(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_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);
 61:       } else {
 62:         MPI_Comm_delete_attr(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:   }

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

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

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

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

114:   PetscObjectGetComm((PetscObject)viewer,&comm);
115:   MPI_Comm_rank(comm,&rank);
116:   MPI_Comm_size(comm,&size);

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

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

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

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

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

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

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

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

191:     Input Parameter:
192: .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()

194:     Output Parameter:
195: .    fd - file pointer

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

199:     Level: intermediate

201:     Fortran Note:
202:     This routine is not supported in Fortran.

204:   Concepts: PetscViewer^file pointer
205:   Concepts: file pointer^getting from PetscViewer

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

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

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

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

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

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

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

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

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

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

252:     Level: developer

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

257:   Concepts: PetscViewerASCII^formating
258:   Concepts: tab^setting

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

272:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
273:   if (iascii) ascii->tab = tabs;
274:   return(0);
275: }

277: /*@
278:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

280:     Not Collective, meaningful on first processor only.

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

287:     Level: developer

289:     Fortran Note:
290:     This routine is not supported in Fortran.

292:   Concepts: PetscViewerASCII^formating
293:   Concepts: tab^retrieval

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

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

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

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

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

321:     Level: developer

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

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

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

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

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

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

351:     Input Parameters:
352: +    viewer - obtained with PetscViewerASCIIOpen()
353: -    tabs - number of tabs

355:     Level: developer

357:     Fortran Note:
358:     This routine is not supported in Fortran.

360:   Concepts: PetscViewerASCII^formating
361:   Concepts: tab^setting

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

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

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

383:     Collective on PetscViewer

385:     Input Parameters:
386: .    viewer - obtained with PetscViewerASCIIOpen()

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

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

396: .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
397:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
398:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
399: @*/
400: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
401: {
402:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
403:   PetscBool         iascii;
404:   PetscErrorCode    ierr;

408:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
409:   if (iascii) ascii->allowsynchronized++;
410:   return(0);
411: }

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

416:     Collective on PetscViewer

418:     Input Parameters:
419: .    viewer - obtained with PetscViewerASCIIOpen()

421:     Level: intermediate
422:     
423:     Notes:
424:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.

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

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

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

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

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

455:     Input Parameters:
456: .    viewer - obtained with PetscViewerASCIIOpen()

458:     Level: developer

460:     Fortran Note:
461:     This routine is not supported in Fortran.

463:   Concepts: PetscViewerASCII^formating
464:   Concepts: tab^setting

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

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

483: /*@C
484:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
485:      lines are tabbed.

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

489:     Input Parameters:
490: .    viewer - obtained with PetscViewerASCIIOpen()

492:     Level: developer

494:     Fortran Note:
495:     This routine is not supported in Fortran.

497:   Concepts: PetscViewerASCII^formating
498:   Concepts: tab^setting

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

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

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

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

525:     Input Parameters:
526: +    viewer - obtained with PetscViewerASCIIOpen()
527: -    flg - PETSC_TRUE or PETSC_FALSE

529:     Level: developer

531:     Fortran Note:
532:     This routine is not supported in Fortran.

534:   Concepts: PetscViewerASCII^formating
535:   Concepts: tab^setting

537: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
538:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
539:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
540: @*/
541: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
542: {
543:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
544:   PetscBool         iascii;
545:   PetscErrorCode    ierr;

549:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
550:   if (iascii) {
551:     if (flg) ascii->tab = ascii->tab_store;
552:     else {
553:       ascii->tab_store = ascii->tab;
554:       ascii->tab       = 0;
555:     }
556:   }
557:   return(0);
558: }

560: /* ----------------------------------------------------------------------- */


563: /*@C
564:     PetscViewerASCIIPrintf - Prints to a file, only from the first
565:     processor in the PetscViewer

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

569:     Input Parameters:
570: +    viewer - obtained with PetscViewerASCIIOpen()
571: -    format - the usual printf() format string

573:     Level: developer

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

579:   Concepts: PetscViewerASCII^printing
580:   Concepts: printing^to file
581:   Concepts: printf

583: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
584:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
585:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
586: @*/
587: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
588: {
589:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
590:   PetscMPIInt       rank;
591:   PetscInt          tab,intab = ascii->tab;
592:   PetscErrorCode    ierr;
593:   FILE              *fd = ascii->fd;
594:   PetscBool         iascii;
595:   int               err;

600:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
601:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
602:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
603:   if (rank) return(0);

605:   if (ascii->bviewer) { /* pass string up to parent viewer */
606:     char        *string;
607:     va_list     Argp;
608:     size_t      fullLength;

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

635:     va_start(Argp,format);
636:     (*PetscVFPrintf)(fd,format,Argp);
637:     err  = fflush(fd);
638:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
639:     if (petsc_history) {
640:       va_start(Argp,format);
641:       tab = intab;
642:       while (tab--) {
643:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
644:       }
645:       (*PetscVFPrintf)(petsc_history,format,Argp);
646:       err  = fflush(petsc_history);
647:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
648:     }
649:     va_end(Argp);
650:   }
651:   return(0);
652: }

654: /*@C
655:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

657:     Collective on PetscViewer

659:   Input Parameters:
660: +  viewer - the PetscViewer; either ASCII or binary
661: -  name - the name of the file it should use

663:     Level: advanced

665: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
666:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

668: @*/
669: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
670: {
672:   char           b[PETSC_MAX_PATH_LEN];

677:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
678:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
679:   return(0);
680: }

682: /*@C
683:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

685:     Not Collective

687:   Input Parameter:
688: .  viewer - the PetscViewer; either ASCII or binary

690:   Output Parameter:
691: .  name - the name of the file it is using

693:     Level: advanced

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

697: @*/
698: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
699: {

705:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
706:   return(0);
707: }

709: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
710: {
711:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

714:   *name = vascii->filename;
715:   return(0);
716: }

718: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
719: {
720:   PetscErrorCode    ierr;
721:   size_t            len;
722:   char              fname[PETSC_MAX_PATH_LEN],*gz;
723:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
724:   PetscBool         isstderr,isstdout;
725:   PetscMPIInt       rank;

728:   PetscViewerFileClose_ASCII(viewer);
729:   if (!name) return(0);
730:   PetscStrallocpy(name,&vascii->filename);

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

735:   PetscStrstr(vascii->filename,".gz",&gz);
736:   if (gz) {
737:     PetscStrlen(gz,&len);
738:     if (len == 3) {
739:       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");
740:       *gz = 0;
741:       vascii->storecompressed = PETSC_TRUE;
742:     }
743:   }
744:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
745:   if (!rank) {
746:     PetscStrcmp(name,"stderr",&isstderr);
747:     PetscStrcmp(name,"stdout",&isstdout);
748:     /* empty filename means stdout */
749:     if (name[0] == 0)  isstdout = PETSC_TRUE;
750:     if (isstderr)      vascii->fd = PETSC_STDERR;
751:     else if (isstdout) vascii->fd = PETSC_STDOUT;
752:     else {


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

792: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
793: {
794:   PetscMPIInt       rank;
795:   PetscErrorCode    ierr;
796:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

799:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
800:   PetscViewerASCIIPushSynchronized(viewer);
801:   PetscViewerCreate(subcomm,outviewer);
802:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
803:   PetscViewerASCIIPushSynchronized(*outviewer);
804:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
805:   ovascii->fd  = vascii->fd;
806:   ovascii->tab = vascii->tab;
807:   ovascii->closefile = PETSC_FALSE;

809:   vascii->sviewer = *outviewer;

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

813:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
814:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
815:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
816:   return(0);
817: }

819: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
820: {
821:   PetscErrorCode    ierr;
822:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

828:   ascii->sviewer             = 0;
829:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
830:   PetscViewerDestroy(outviewer);
831:   return(0);
832: }

834: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
835: {
836:   PetscErrorCode    ierr;
837:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

840:   if (ascii->filename) {
841:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
842:   }
843:   return(0);
844: }

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


850: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
851:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
852:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

854:   Level: beginner

856: M*/
857: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
858: {
859:   PetscViewer_ASCII *vascii;
860:   PetscErrorCode    ierr;

863:   PetscNewLog(viewer,&vascii);
864:   viewer->data = (void*)vascii;

866:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
867:   viewer->ops->flush            = PetscViewerFlush_ASCII;
868:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
869:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
870:   viewer->ops->view             = PetscViewerView_ASCII;
871:   viewer->ops->read             = PetscViewerASCIIRead;

873:   /* defaults to stdout unless set with PetscViewerFileSetName() */
874:   vascii->fd        = PETSC_STDOUT;
875:   vascii->mode      = FILE_MODE_WRITE;
876:   vascii->bviewer   = 0;
877:   vascii->subviewer = 0;
878:   vascii->sviewer   = 0;
879:   vascii->tab       = 0;
880:   vascii->tab_store = 0;
881:   vascii->filename  = 0;
882:   vascii->closefile = PETSC_TRUE;

884:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
885:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
886:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
887:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
888:   return(0);
889: }

891: /*@C
892:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
893:     several processors.  Output of the first processor is followed by that of the
894:     second, etc.

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

898:     Input Parameters:
899: +   viewer - the ASCII PetscViewer
900: -   format - the usual printf() format string

902:     Level: intermediate

904:     Notes:
905:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
906:     Then you can do multiple independent calls to this routine.
907:     The actual synchronized print is then done using PetscViewerFlush().
908:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
909:     to conclude the "synchronized session".
910:     So the typical calling sequence looks like
911: $ PetscViewerASCIIPushSynchronized(viewer);
912: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
913: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
914: $ ...
915: $ PetscViewerFlush(viewer);
916: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
917: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
918: $ ...
919: $ PetscViewerFlush(viewer);
920: $ PetscViewerASCIIPopSynchronized(viewer);    

922:     Fortran Note:
923:       Can only print a single character* string

925: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
926:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
927:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
928: @*/
929: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
930: {
931:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
932:   PetscErrorCode    ierr;
933:   PetscMPIInt       rank;
934:   PetscInt          tab = vascii->tab;
935:   MPI_Comm          comm;
936:   FILE              *fp;
937:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
938:   int               err;

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

947:   PetscObjectGetComm((PetscObject)viewer,&comm);
948:   MPI_Comm_rank(comm,&rank);

950:   if (vascii->bviewer) {
951:     hasbviewer = PETSC_TRUE;
952:     if (!rank) {
953:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
954:       PetscObjectGetComm((PetscObject)viewer,&comm);
955:       MPI_Comm_rank(comm,&rank);
956:     }
957:   }

959:   fp   = vascii->fd;

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

976:     while (tab--) {
977:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
978:     }

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

997:     PetscNew(&next);
998:     if (vascii->petsc_printfqueue) {
999:       vascii->petsc_printfqueue->next = next;
1000:       vascii->petsc_printfqueue       = next;
1001:     } else {
1002:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
1003:     }
1004:     vascii->petsc_printfqueuelength++;
1005:     next->size = QUEUESTRINGSIZE;
1006:     PetscMalloc1(next->size, &next->string);
1007:     PetscMemzero(next->string,next->size);
1008:     string     = next->string;
1009:     tab       *= 2;
1010:     while (tab--) {
1011:       *string++ = ' ';
1012:     }
1013:     va_start(Argp,format);
1014:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1015:     va_end(Argp);
1016:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
1017:       PetscFree(next->string);
1018:       next->size = fullLength + 2*vascii->tab;
1019:       PetscMalloc1(next->size, &next->string);
1020:       PetscMemzero(next->string,next->size);
1021:       string     = next->string;
1022:       tab        = 2*vascii->tab;
1023:       while (tab--) {
1024:         *string++ = ' ';
1025:       }
1026:       va_start(Argp,format);
1027:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1028:       va_end(Argp);
1029:     }
1030:   }
1031:   return(0);
1032: }

1034: /*@C
1035:    PetscViewerASCIIRead - Reads from a ASCII file

1037:    Only process 0 in the PetscViewer may call this

1039:    Input Parameters:
1040: +  viewer - the ascii viewer
1041: .  data - location to write the data
1042: .  num - number of items of data to read
1043: -  datatype - type of data to read

1045:    Output Parameters:
1046: .  count - number of items of data actually read, or NULL

1048:    Level: beginner

1050:    Concepts: ascii files

1052: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1053:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1054:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1055: @*/
1056: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1057: {
1058:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1059:   FILE              *fd = vascii->fd;
1060:   PetscInt           i;
1061:   int                ret = 0;
1062:   PetscMPIInt        rank;
1063:   PetscErrorCode     ierr;

1067:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
1068:   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1069:   for (i=0; i<num; i++) {
1070:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1071:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1072:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1073:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1074:     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1075:     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1076:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1077:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1078: #if defined(PETSC_USE_REAL___FLOAT128)
1079:     else if (dtype == PETSC___FLOAT128) {
1080:       double tmp;
1081:       ret = fscanf(fd, "%lg", &tmp);
1082:       ((__float128*)data)[i] = tmp;
1083:     }
1084: #endif
1085:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1086:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1087:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1088:   }
1089:   if (count) *count = i;
1090:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1091:   return(0);
1092: }