Actual source code: filev.c

petsc-3.14.6 2021-03-30
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:   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 && 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 && (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) {
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.


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.


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

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

275: /*@
276:     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.

278:     Not Collective, meaningful on first processor only.

280:     Input Parameters:
281: .    viewer - obtained with PetscViewerASCIIOpen()

283:     Output Parameters:
284: .    tabs - number of tabs

286:     Level: developer

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


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

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

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

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

314:     Input Parameters:
315: +    viewer - obtained with PetscViewerASCIIOpen()
316: -    tabs - number of tabs

318:     Level: developer

320:     Fortran Note:
321:     This routine is not supported in Fortran.


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.


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

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

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

376:     Collective on PetscViewer

378:     Input Parameters:
379: .    viewer - obtained with PetscViewerASCIIOpen()

381:     Level: intermediate

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


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

399:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
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:     Notes:
416:     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.


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

431:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
432:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
433:   if (iascii) {
434:     ascii->allowsynchronized--;
435:     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
436:   }
437:   return(0);
438: }

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

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

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

449:     Level: developer

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


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.


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

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

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

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

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

516:     Level: developer

518:     Fortran Note:
519:     This routine is not supported in Fortran.


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

534:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
535:   if (iascii) {
536:     if (flg) ascii->tab = ascii->tab_store;
537:     else {
538:       ascii->tab_store = ascii->tab;
539:       ascii->tab       = 0;
540:     }
541:   }
542:   return(0);
543: }

545: /* ----------------------------------------------------------------------- */


548: /*@C
549:     PetscViewerASCIIPrintf - Prints to a file, only from the first
550:     processor in the PetscViewer

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

554:     Input Parameters:
555: +    viewer - obtained with PetscViewerASCIIOpen()
556: -    format - the usual printf() format string

558:     Level: developer

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

564: .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
565:           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
566:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
567: @*/
568: PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
569: {
570:   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
571:   PetscMPIInt       rank;
572:   PetscInt          tab,intab = ascii->tab;
573:   PetscErrorCode    ierr;
574:   FILE              *fd = ascii->fd;
575:   PetscBool         iascii;
576:   int               err;

580:   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
582:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
583:   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
584:   MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);
585:   if (rank) return(0);

587:   if (ascii->bviewer) { /* pass string up to parent viewer */
588:     char        *string;
589:     va_list     Argp;
590:     size_t      fullLength;

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

617:     va_start(Argp,format);
618:     (*PetscVFPrintf)(fd,format,Argp);
619:     err  = fflush(fd);
620:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
621:     if (petsc_history) {
622:       va_start(Argp,format);
623:       tab = intab;
624:       while (tab--) {
625:         PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");
626:       }
627:       (*PetscVFPrintf)(petsc_history,format,Argp);
628:       err  = fflush(petsc_history);
629:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
630:     }
631:     va_end(Argp);
632:   }
633:   return(0);
634: }

636: /*@C
637:      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.

639:     Collective on PetscViewer

641:   Input Parameters:
642: +  viewer - the PetscViewer; either ASCII or binary
643: -  name - the name of the file it should use

645:     Level: advanced

647: .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
648:           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()

650: @*/
651: PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
652: {
654:   char           filename[PETSC_MAX_PATH_LEN];

659:   PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));
660:   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
661:   return(0);
662: }

664: /*@C
665:      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.

667:     Not Collective

669:   Input Parameter:
670: .  viewer - the PetscViewer; either ASCII or binary

672:   Output Parameter:
673: .  name - the name of the file it is using

675:     Level: advanced

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

679: @*/
680: PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
681: {

687:   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
688:   return(0);
689: }

691: PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
692: {
693:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

696:   *name = vascii->filename;
697:   return(0);
698: }

700: PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
701: {
702:   PetscErrorCode    ierr;
703:   size_t            len;
704:   char              fname[PETSC_MAX_PATH_LEN],*gz;
705:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
706:   PetscBool         isstderr,isstdout;
707:   PetscMPIInt       rank;

710:   PetscViewerFileClose_ASCII(viewer);
711:   if (!name) return(0);
712:   PetscStrallocpy(name,&vascii->filename);

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

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


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

774: PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
775: {
776:   PetscErrorCode    ierr;
777:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;

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

787:      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
788:      PCView_GASM().
789:   */
790:   PetscViewerASCIIPushSynchronized(viewer);
791:   PetscViewerCreate(subcomm,outviewer);
792:   PetscViewerSetType(*outviewer,PETSCVIEWERASCII);
793:   PetscViewerASCIIPushSynchronized(*outviewer);
794:   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
795:   ovascii->fd  = vascii->fd;
796:   ovascii->tab = vascii->tab;
797:   ovascii->closefile = PETSC_FALSE;

799:   vascii->sviewer = *outviewer;

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

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:   PetscViewerASCIIPopSynchronized(*outviewer);
818:   ascii->sviewer             = NULL;
819:   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
820:   PetscViewerDestroy(outviewer);
821:   PetscViewerASCIIPopSynchronized(viewer);
822:   return(0);
823: }

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

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

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


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

845:   Level: beginner

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

854:   PetscNewLog(viewer,&vascii);
855:   viewer->data = (void*)vascii;

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

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

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

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

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

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

893:     Level: intermediate

895:     Notes:
896:     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
897:     Then you can do multiple independent calls to this routine.
898:     The actual synchronized print is then done using PetscViewerFlush().
899:     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
900:     to conclude the "synchronized session".
901:     So the typical calling sequence looks like
902: $ PetscViewerASCIIPushSynchronized(viewer);
903: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
904: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
905: $ ...
906: $ PetscViewerFlush(viewer);
907: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
908: $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
909: $ ...
910: $ PetscViewerFlush(viewer);
911: $ PetscViewerASCIIPopSynchronized(viewer);

913:     Fortran Note:
914:       Can only print a single character* string

916: .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
917:           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
918:           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
919: @*/
920: PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
921: {
922:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
923:   PetscErrorCode    ierr;
924:   PetscMPIInt       rank;
925:   PetscInt          tab = vascii->tab;
926:   MPI_Comm          comm;
927:   FILE              *fp;
928:   PetscBool         iascii,hasbviewer = PETSC_FALSE;
929:   int               err;

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

938:   PetscObjectGetComm((PetscObject)viewer,&comm);
939:   MPI_Comm_rank(comm,&rank);

941:   if (vascii->bviewer) {
942:     hasbviewer = PETSC_TRUE;
943:     if (!rank) {
944:       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
945:       PetscObjectGetComm((PetscObject)viewer,&comm);
946:       MPI_Comm_rank(comm,&rank);
947:     }
948:   }

950:   fp   = vascii->fd;

952:   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
953:     va_list Argp;
954:     /* flush my own messages that I may have queued up */
955:     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
956:     PetscInt    i;
957:     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
958:       PetscFPrintf(comm,fp,"%s",next->string);
959:       previous = next;
960:       next     = next->next;
961:       PetscFree(previous->string);
962:       PetscFree(previous);
963:     }
964:     vascii->petsc_printfqueue       = NULL;
965:     vascii->petsc_printfqueuelength = 0;

967:     while (tab--) {
968:       PetscFPrintf(PETSC_COMM_SELF,fp,"  ");
969:     }

971:     va_start(Argp,format);
972:     (*PetscVFPrintf)(fp,format,Argp);
973:     err  = fflush(fp);
974:     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
975:     if (petsc_history) {
976:       va_start(Argp,format);
977:       (*PetscVFPrintf)(petsc_history,format,Argp);
978:       err  = fflush(petsc_history);
979:       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
980:     }
981:     va_end(Argp);
982:   } else { /* other processors add to queue */
983:     char        *string;
984:     va_list     Argp;
985:     size_t      fullLength;
986:     PrintfQueue next;

988:     PetscNew(&next);
989:     if (vascii->petsc_printfqueue) {
990:       vascii->petsc_printfqueue->next = next;
991:       vascii->petsc_printfqueue       = next;
992:     } else {
993:       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
994:     }
995:     vascii->petsc_printfqueuelength++;
996:     next->size = QUEUESTRINGSIZE;
997:     PetscCalloc1(next->size, &next->string);
998:     string     = next->string;
999:     tab       *= 2;
1000:     while (tab--) {
1001:       *string++ = ' ';
1002:     }
1003:     va_start(Argp,format);
1004:     PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);
1005:     va_end(Argp);
1006:     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
1007:       PetscFree(next->string);
1008:       next->size = fullLength + 2*vascii->tab;
1009:       PetscCalloc1(next->size, &next->string);
1010:       string     = next->string;
1011:       tab        = 2*vascii->tab;
1012:       while (tab--) {
1013:         *string++ = ' ';
1014:       }
1015:       va_start(Argp,format);
1016:       PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);
1017:       va_end(Argp);
1018:     }
1019:   }
1020:   return(0);
1021: }

1023: /*@C
1024:    PetscViewerASCIIRead - Reads from a ASCII file

1026:    Only process 0 in the PetscViewer may call this

1028:    Input Parameters:
1029: +  viewer - the ascii viewer
1030: .  data - location to write the data
1031: .  num - number of items of data to read
1032: -  datatype - type of data to read

1034:    Output Parameters:
1035: .  count - number of items of data actually read, or NULL

1037:    Level: beginner

1039: .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1040:           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1041:           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1042: @*/
1043: PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1044: {
1045:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1046:   FILE              *fd = vascii->fd;
1047:   PetscInt           i;
1048:   int                ret = 0;
1049:   PetscMPIInt        rank;
1050:   PetscErrorCode     ierr;

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