Actual source code: filev.c

petsc-3.9.4 2018-09-11
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

191: +   viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
192: -   fd - file pointer

194:     Level: intermediate

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

199:   Concepts: PetscViewer^file pointer
200:   Concepts: file pointer^getting from PetscViewer

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

210:   *fd = vascii->fd;
211:   return(0);
212: }

214: PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
215: {
216:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

219:   *mode = vascii->mode;
220:   return(0);
221: }

223: PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
224: {
225:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

228:   vascii->mode = mode;
229:   return(0);
230: }

232: /*
233:    If petsc_history is on, then all Petsc*Printf() results are saved
234:    if the appropriate (usually .petschistory) file.
235: */
236: extern FILE *petsc_history;

238: /*@
239:     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times

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

243:     Input Parameters:
244: +    viewer - obtained with PetscViewerASCIIOpen()
245: -    tabs - number of tabs

247:     Level: developer

249:     Fortran Note:
250:     This routine is not supported in Fortran.

252:   Concepts: PetscViewerASCII^formating
253:   Concepts: tab^setting

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

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

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

275:     Not Collective, meaningful on first processor only.

277:     Input Parameters:
278: .    viewer - obtained with PetscViewerASCIIOpen()
279:     Output Parameters:
280: .    tabs - number of tabs

282:     Level: developer

284:     Fortran Note:
285:     This routine is not supported in Fortran.

287:   Concepts: PetscViewerASCII^formating
288:   Concepts: tab^retrieval

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

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

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

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

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

316:     Level: developer

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

321:   Concepts: PetscViewerASCII^formating
322:   Concepts: tab^setting

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

336:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
337:   if (iascii) ascii->tab += tabs;
338:   return(0);
339: }

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

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

346:     Input Parameters:
347: +    viewer - obtained with PetscViewerASCIIOpen()
348: -    tabs - number of tabs

350:     Level: developer

352:     Fortran Note:
353:     This routine is not supported in Fortran.

355:   Concepts: PetscViewerASCII^formating
356:   Concepts: tab^setting

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

370:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
371:   if (iascii) ascii->tab -= tabs;
372:   return(0);
373: }

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

378:     Collective on PetscViewer

380:     Input Parameters:
381: .    viewer - obtained with PetscViewerASCIIOpen()

383:     Level: intermediate

385:   Concepts: PetscViewerASCII^formating
386:   Concepts: tab^setting

388: .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
389:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
390:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
391: @*/
392: PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
393: {
394:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
395:   PetscBool         iascii;
396:   PetscErrorCode    ierr;

400:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
401:   if (iascii) ascii->allowsynchronized++;
402:   return(0);
403: }

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

408:     Collective on PetscViewer

410:     Input Parameters:
411: .    viewer - obtained with PetscViewerASCIIOpen()

413:     Level: intermediate

415:   Concepts: PetscViewerASCII^formating
416:   Concepts: tab^setting

418: .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
419:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
420:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
421: @*/
422: PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
423: {
424:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
425:   PetscBool         iascii;
426:   PetscErrorCode    ierr;

430:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
431:   if (iascii) {
432:     ascii->allowsynchronized--;
433:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
434:   }
435:   return(0);
436: }

438: /*@C
439:     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
440:      lines are tabbed.

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

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

447:     Level: developer

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

452:   Concepts: PetscViewerASCII^formating
453:   Concepts: tab^setting

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

467:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
468:   if (iascii) ascii->tab++;
469:   return(0);
470: }

472: /*@C
473:     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
474:      lines are tabbed.

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

478:     Input Parameters:
479: .    viewer - obtained with PetscViewerASCIIOpen()

481:     Level: developer

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

486:   Concepts: PetscViewerASCII^formating
487:   Concepts: tab^setting

489: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
490:           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
491:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
492: @*/
493: PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
494: {
495:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
496:   PetscErrorCode    ierr;
497:   PetscBool         iascii;

501:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
502:   if (iascii) {
503:     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
504:     ascii->tab--;
505:   }
506:   return(0);
507: }

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

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

514:     Input Parameters:
515: +    viewer - obtained with PetscViewerASCIIOpen()
516: -    flg - PETSC_TRUE or PETSC_FALSE

518:     Level: developer

520:     Fortran Note:
521:     This routine is not supported in Fortran.

523:   Concepts: PetscViewerASCII^formating
524:   Concepts: tab^setting

526: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
527:           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
528:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
529: @*/
530: PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
531: {
532:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
533:   PetscBool         iascii;
534:   PetscErrorCode    ierr;

538:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
539:   if (iascii) {
540:     if (flg) ascii->tab = ascii->tab_store;
541:     else {
542:       ascii->tab_store = ascii->tab;
543:       ascii->tab       = 0;
544:     }
545:   }
546:   return(0);
547: }

549: /* ----------------------------------------------------------------------- */


552: /*@C
553:     PetscViewerASCIIPrintf - Prints to a file, only from the first
554:     processor in the PetscViewer

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

558:     Input Parameters:
559: +    viewer - obtained with PetscViewerASCIIOpen()
560: -    format - the usual printf() format string

562:     Level: developer

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

568:   Concepts: PetscViewerASCII^printing
569:   Concepts: printing^to file
570:   Concepts: printf

572: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
573:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
574:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
575: @*/
576: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
577: {
578:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
579:   PetscMPIInt       rank;
580:   PetscInt          tab,intab = ascii->tab;
581:   PetscErrorCode    ierr;
582:   FILE              *fd = ascii->fd;
583:   PetscBool         iascii;
584:   int               err;

589:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
590:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
591:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
592:   if (rank) return(0);

594:   if (ascii->bviewer) { /* pass string up to parent viewer */
595:     char        *string;
596:     va_list     Argp;
597:     size_t      fullLength;

599:     PetscCalloc1(QUEUESTRINGSIZE, &string);
600:     va_start(Argp,format);
601:     PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);
602:     va_end(Argp);
603:     PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);
604:     PetscFree(string);
605:   } else { /* write directly to file */
606:     va_list Argp;
607:     /* flush my own messages that I may have queued up */
608:     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
609:     PetscInt    i;
610:     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
611:       PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);
612:       previous = next;
613:       next     = next->next;
614:       PetscFree(previous->string);
615:       PetscFree(previous);
616:     }
617:     ascii->petsc_printfqueue       = 0;
618:     ascii->petsc_printfqueuelength = 0;
619:     tab = intab;
620:     while (tab--) {
621:       PetscFPrintf(PETSC_COMM_SELF,fd,"  ");
622:     }

624:     va_start(Argp,format);
625:     (*PetscVFPrintf)(fd,format,Argp);
626:     err  = fflush(fd);
627:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
628:     if (petsc_history) {
629:       va_start(Argp,format);
630:       tab = intab;
631:       while (tab--) {
632:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
633:       }
634:       (*PetscVFPrintf)(petsc_history,format,Argp);
635:       err  = fflush(petsc_history);
636:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
637:     }
638:     va_end(Argp);
639:   }
640:   return(0);
641: }

643: /*@C
644:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

646:     Collective on PetscViewer

648:   Input Parameters:
649: +  viewer - the PetscViewer; either ASCII or binary
650: -  name - the name of the file it should use

652:     Level: advanced

654: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
655:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

657: @*/
658: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
659: {
661:   char           b[PETSC_MAX_PATH_LEN];

666:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));
667:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));
668:   return(0);
669: }

671: /*@C
672:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

674:     Not Collective

676:   Input Parameter:
677: .  viewer - the PetscViewer; either ASCII or binary

679:   Output Parameter:
680: .  name - the name of the file it is using

682:     Level: advanced

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

686: @*/
687: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
688: {

694:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
695:   return(0);
696: }

698: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
699: {
700:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

703:   *name = vascii->filename;
704:   return(0);
705: }

707: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
708: {
709:   PetscErrorCode    ierr;
710:   size_t            len;
711:   char              fname[PETSC_MAX_PATH_LEN],*gz;
712:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
713:   PetscBool         isstderr,isstdout;
714:   PetscMPIInt       rank;

717:   PetscViewerFileClose_ASCII(viewer);
718:   if (!name) return(0);
719:   PetscStrallocpy(name,&vascii->filename);

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

724:   PetscStrstr(vascii->filename,".gz",&gz);
725:   if (gz) {
726:     PetscStrlen(gz,&len);
727:     if (len == 3) {
728:       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");
729:       *gz = 0;
730:       vascii->storecompressed = PETSC_TRUE;
731:     }
732:   }
733:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
734:   if (!rank) {
735:     PetscStrcmp(name,"stderr",&isstderr);
736:     PetscStrcmp(name,"stdout",&isstdout);
737:     /* empty filename means stdout */
738:     if (name[0] == 0)  isstdout = PETSC_TRUE;
739:     if (isstderr)      vascii->fd = PETSC_STDERR;
740:     else if (isstdout) vascii->fd = PETSC_STDOUT;
741:     else {


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

781: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
782: {
783:   PetscMPIInt       rank;
784:   PetscErrorCode    ierr;
785:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

788:   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
789:   PetscViewerASCIIPushSynchronized(viewer);
790:   PetscViewerCreate(subcomm,outviewer);
791:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
792:   PetscViewerASCIIPushSynchronized(*outviewer);
793:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
794:   ovascii->fd  = vascii->fd;
795:   ovascii->tab = vascii->tab;
796:   ovascii->closefile = PETSC_FALSE;

798:   vascii->sviewer = *outviewer;

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

802:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
803:   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
804:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
805:   return(0);
806: }

808: PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
809: {
810:   PetscErrorCode    ierr;
811:   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;

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

817:   ascii->sviewer             = 0;
818:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
819:   PetscViewerDestroy(outviewer);
820:   return(0);
821: }

823: PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
824: {
825:   PetscErrorCode    ierr;
826:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;

829:   if (ascii->filename) {
830:     PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);
831:   }
832:   return(0);
833: }

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


839: .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
840:            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
841:            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()

843:   Level: beginner

845: M*/
846: PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
847: {
848:   PetscViewer_ASCII *vascii;
849:   PetscErrorCode    ierr;

852:   PetscNewLog(viewer,&vascii);
853:   viewer->data = (void*)vascii;

855:   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
856:   viewer->ops->flush            = PetscViewerFlush_ASCII;
857:   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
858:   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
859:   viewer->ops->view             = PetscViewerView_ASCII;
860:   viewer->ops->read             = PetscViewerASCIIRead;

862:   /* defaults to stdout unless set with PetscViewerFileSetName() */
863:   vascii->fd        = PETSC_STDOUT;
864:   vascii->mode      = FILE_MODE_WRITE;
865:   vascii->bviewer   = 0;
866:   vascii->subviewer = 0;
867:   vascii->sviewer   = 0;
868:   vascii->tab       = 0;
869:   vascii->tab_store = 0;
870:   vascii->filename  = 0;
871:   vascii->closefile = PETSC_TRUE;

873:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);
874:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);
875:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);
876:   PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);
877:   return(0);
878: }

880: /*@C
881:     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
882:     several processors.  Output of the first processor is followed by that of the
883:     second, etc.

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

887:     Input Parameters:
888: +   viewer - the ASCII PetscViewer
889: -   format - the usual printf() format string

891:     Level: intermediate

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

895:     Fortran Note:
896:       Can only print a single character* string

898: .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
899:           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
900:           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()

902: @*/
903: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
904: {
905:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
906:   PetscErrorCode    ierr;
907:   PetscMPIInt       rank;
908:   PetscInt          tab = vascii->tab;
909:   MPI_Comm          comm;
910:   FILE              *fp;
911:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
912:   int               err;

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

921:   PetscObjectGetComm((PetscObject)viewer,&comm);
922:   MPI_Comm_rank(comm,&rank);

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

933:   fp   = vascii->fd;

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

950:     while (tab--) {
951:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
952:     }

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

971:     PetscNew(&next);
972:     if (vascii->petsc_printfqueue) {
973:       vascii->petsc_printfqueue->next = next;
974:       vascii->petsc_printfqueue       = next;
975:     } else {
976:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
977:     }
978:     vascii->petsc_printfqueuelength++;
979:     next->size = QUEUESTRINGSIZE;
980:     PetscMalloc1(next->size, &next->string);
981:     PetscMemzero(next->string,next->size);
982:     string     = next->string;
983:     tab       *= 2;
984:     while (tab--) {
985:       *string++ = ' ';
986:     }
987:     va_start(Argp,format);
988:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
989:     va_end(Argp);
990:   }
991:   return(0);
992: }

994: /*@C
995:    PetscViewerASCIIRead - Reads from am ASCII file

997:    Collective on MPI_Comm

999:    Input Parameters:
1000: +  viewer - the ascii viewer
1001: .  data - location to write the data
1002: .  num - number of items of data to read
1003: -  datatype - type of data to read

1005:    Output Parameters:
1006: .  count - number of items of data actually read, or NULL

1008:    Level: beginner

1010:    Concepts: ascii files

1012: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1013:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1014:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscBinaryViewerRead()
1015: @*/
1016: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1017: {
1018:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1019:   FILE              *fd = vascii->fd;
1020:   PetscInt           i;
1021:   int                ret = 0;

1025:   for (i=0; i<num; i++) {
1026:     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1027:     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1028:     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1029:     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
1030:     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1031:     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1032: #if defined(PETSC_USE_REAL___FLOAT128)
1033:     else if (dtype == PETSC___FLOAT128) {
1034:       double tmp;
1035:       ret = fscanf(fd, "%lg", &tmp);
1036:       ((__float128*)data)[i] = tmp;
1037:     }
1038: #endif
1039:     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1040:     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1041:     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1042:   }
1043:   if (count) *count = i;
1044:   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1045:   return(0);
1046: }