xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision cac4c232dc4f93991e342196e27ef7b0655dac7b)
15c6c1daeSBarry Smith 
2665c2dedSJed Brown #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I "petscviewer.h" I*/
35c6c1daeSBarry Smith 
45c6c1daeSBarry Smith #define QUEUESTRINGSIZE 8192
55c6c1daeSBarry Smith 
65c6c1daeSBarry Smith static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
75c6c1daeSBarry Smith {
85c6c1daeSBarry Smith   PetscMPIInt       rank;
95c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
105c6c1daeSBarry Smith   int               err;
115c6c1daeSBarry Smith 
125c6c1daeSBarry Smith   PetscFunctionBegin;
1328b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
149566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
15dd400576SPatrick Sanan   if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
165c6c1daeSBarry Smith     if (vascii->fd && vascii->closefile) {
175c6c1daeSBarry Smith       err = fclose(vascii->fd);
1828b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
195c6c1daeSBarry Smith     }
205c6c1daeSBarry Smith     if (vascii->storecompressed) {
215c6c1daeSBarry Smith       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
225c6c1daeSBarry Smith       FILE *fp;
239566063dSJacob Faibussowitsch       PetscCall(PetscStrncpy(par,"gzip ",sizeof(par)));
249566063dSJacob Faibussowitsch       PetscCall(PetscStrlcat(par,vascii->filename,sizeof(par)));
255c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
269566063dSJacob Faibussowitsch       PetscCall(PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp));
272c71b3e2SJacob Faibussowitsch       PetscCheckFalse(fgets(buf,1024,fp),PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
289566063dSJacob Faibussowitsch       PetscCall(PetscPClose(PETSC_COMM_SELF,fp));
295c6c1daeSBarry Smith #else
305c6c1daeSBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
315c6c1daeSBarry Smith #endif
325c6c1daeSBarry Smith     }
335c6c1daeSBarry Smith   }
349566063dSJacob Faibussowitsch   PetscCall(PetscFree(vascii->filename));
355c6c1daeSBarry Smith   PetscFunctionReturn(0);
365c6c1daeSBarry Smith }
375c6c1daeSBarry Smith 
385c6c1daeSBarry Smith /* ----------------------------------------------------------------------*/
395c6c1daeSBarry Smith PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
405c6c1daeSBarry Smith {
415c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
425c6c1daeSBarry Smith   PetscViewerLink   *vlink;
435c6c1daeSBarry Smith   PetscBool         flg;
445c6c1daeSBarry Smith 
455c6c1daeSBarry Smith   PetscFunctionBegin;
4628b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
479566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
489566063dSJacob Faibussowitsch   PetscCall(PetscFree(vascii));
495c6c1daeSBarry Smith 
505c6c1daeSBarry Smith   /* remove the viewer from the list in the MPI Communicator */
515c6c1daeSBarry Smith   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
529566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0));
535c6c1daeSBarry Smith   }
545c6c1daeSBarry Smith 
559566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg));
565c6c1daeSBarry Smith   if (flg) {
575c6c1daeSBarry Smith     if (vlink && vlink->viewer == viewer) {
58e5840a18SBarry Smith       if (vlink->next) {
599566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next));
60e5840a18SBarry Smith       } else {
619566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval));
62e5840a18SBarry Smith       }
639566063dSJacob Faibussowitsch       PetscCall(PetscFree(vlink));
645c6c1daeSBarry Smith     } else {
655c6c1daeSBarry Smith       while (vlink && vlink->next) {
665c6c1daeSBarry Smith         if (vlink->next->viewer == viewer) {
675c6c1daeSBarry Smith           PetscViewerLink *nv = vlink->next;
685c6c1daeSBarry Smith           vlink->next = vlink->next->next;
699566063dSJacob Faibussowitsch           PetscCall(PetscFree(nv));
705c6c1daeSBarry Smith         }
715c6c1daeSBarry Smith         vlink = vlink->next;
725c6c1daeSBarry Smith       }
735c6c1daeSBarry Smith     }
745c6c1daeSBarry Smith   }
75aa139df6SJed Brown 
76aa139df6SJed Brown   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
77aa139df6SJed Brown     PetscViewer aviewer;
789566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg));
79aa139df6SJed Brown     if (flg && aviewer == viewer) {
809566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval));
81aa139df6SJed Brown     }
82aa139df6SJed Brown   }
83aa139df6SJed Brown   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
84aa139df6SJed Brown     PetscViewer aviewer;
859566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg));
86aa139df6SJed Brown     if (flg && aviewer == viewer) {
879566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval));
88aa139df6SJed Brown     }
89aa139df6SJed Brown   }
905c6c1daeSBarry Smith   PetscFunctionReturn(0);
915c6c1daeSBarry Smith }
925c6c1daeSBarry Smith 
933f08860eSBarry Smith PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
945c6c1daeSBarry Smith {
955c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
965fd66863SKarl Rupp 
975c6c1daeSBarry Smith   PetscFunctionBegin;
989566063dSJacob Faibussowitsch   PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer));
995c6c1daeSBarry Smith   PetscFunctionReturn(0);
1005c6c1daeSBarry Smith }
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
1035c6c1daeSBarry Smith {
1045c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1055c6c1daeSBarry Smith   int               err;
106559f443fSBarry Smith   MPI_Comm          comm;
107559f443fSBarry Smith   PetscMPIInt       rank,size;
108559f443fSBarry Smith   FILE              *fd = vascii->fd;
1095c6c1daeSBarry Smith 
1105c6c1daeSBarry Smith   PetscFunctionBegin;
11128b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
1129566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
1139566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
1149566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
115559f443fSBarry Smith 
116dd400576SPatrick Sanan   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
1175c6c1daeSBarry Smith     err = fflush(vascii->fd);
11828b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
1195c6c1daeSBarry Smith   }
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   if (vascii->allowsynchronized) {
122559f443fSBarry Smith     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
123559f443fSBarry Smith     char          *message;
124559f443fSBarry Smith     MPI_Status    status;
125559f443fSBarry Smith 
1269566063dSJacob Faibussowitsch     PetscCall(PetscCommDuplicate(comm,&comm,&tag));
127559f443fSBarry Smith 
128559f443fSBarry Smith     /* First processor waits for messages from all other processors */
129dd400576SPatrick Sanan     if (rank == 0) {
130559f443fSBarry Smith       /* flush my own messages that I may have queued up */
131559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
132559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
133559f443fSBarry Smith         if (!vascii->bviewer) {
1349566063dSJacob Faibussowitsch           PetscCall(PetscFPrintf(comm,fd,"%s",next->string));
135559f443fSBarry Smith         } else {
1369566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string));
137559f443fSBarry Smith         }
138559f443fSBarry Smith         previous = next;
139559f443fSBarry Smith         next     = next->next;
1409566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1419566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
142559f443fSBarry Smith       }
14302c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
144559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
145559f443fSBarry Smith       for (i=1; i<size; i++) {
146559f443fSBarry Smith         /* to prevent a flood of messages to process zero, request each message separately */
1479566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&dummy,1,MPI_INT,i,tag,comm));
1489566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status));
149559f443fSBarry Smith         for (j=0; j<n; j++) {
150559f443fSBarry Smith           PetscMPIInt size = 0;
151559f443fSBarry Smith 
1529566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status));
1539566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(size, &message));
1549566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status));
155559f443fSBarry Smith           if (!vascii->bviewer) {
1569566063dSJacob Faibussowitsch             PetscCall(PetscFPrintf(comm,fd,"%s",message));
157559f443fSBarry Smith           } else {
1589566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message));
159559f443fSBarry Smith           }
1609566063dSJacob Faibussowitsch           PetscCall(PetscFree(message));
161559f443fSBarry Smith         }
162559f443fSBarry Smith       }
163559f443fSBarry Smith     } else { /* other processors send queue to processor 0 */
164559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
165559f443fSBarry Smith 
1669566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status));
1679566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm));
168559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
1699566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&next->size,1,MPI_INT,0,tag,comm));
1709566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm));
171559f443fSBarry Smith         previous = next;
172559f443fSBarry Smith         next     = next->next;
1739566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1749566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
175559f443fSBarry Smith       }
17602c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
177559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
178559f443fSBarry Smith     }
1799566063dSJacob Faibussowitsch     PetscCall(PetscCommDestroy(&comm));
1805c6c1daeSBarry Smith   }
1815c6c1daeSBarry Smith   PetscFunctionReturn(0);
1825c6c1daeSBarry Smith }
1835c6c1daeSBarry Smith 
1845c6c1daeSBarry Smith /*@C
1855c6c1daeSBarry Smith     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
1865c6c1daeSBarry Smith 
187f8859db6SBarry Smith     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
1885c6c1daeSBarry Smith 
189f8859db6SBarry Smith     Input Parameter:
190f8859db6SBarry Smith .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
191f8859db6SBarry Smith 
192f8859db6SBarry Smith     Output Parameter:
193f8859db6SBarry Smith .    fd - file pointer
194f8859db6SBarry Smith 
195f8859db6SBarry Smith     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
1965c6c1daeSBarry Smith 
1975c6c1daeSBarry Smith     Level: intermediate
1985c6c1daeSBarry Smith 
1995c6c1daeSBarry Smith     Fortran Note:
2005c6c1daeSBarry Smith     This routine is not supported in Fortran.
2015c6c1daeSBarry Smith 
2025c6c1daeSBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
2035c6c1daeSBarry Smith           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
2045c6c1daeSBarry Smith @*/
2055c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
2065c6c1daeSBarry Smith {
2075c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2085c6c1daeSBarry Smith 
2095c6c1daeSBarry Smith   PetscFunctionBegin;
2105c6c1daeSBarry Smith   *fd = vascii->fd;
2115c6c1daeSBarry Smith   PetscFunctionReturn(0);
2125c6c1daeSBarry Smith }
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
2155c6c1daeSBarry Smith {
2165c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2175c6c1daeSBarry Smith 
2185c6c1daeSBarry Smith   PetscFunctionBegin;
2195c6c1daeSBarry Smith   *mode = vascii->mode;
2205c6c1daeSBarry Smith   PetscFunctionReturn(0);
2215c6c1daeSBarry Smith }
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
2245c6c1daeSBarry Smith {
2255c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2265c6c1daeSBarry Smith 
2275c6c1daeSBarry Smith   PetscFunctionBegin;
2285c6c1daeSBarry Smith   vascii->mode = mode;
2295c6c1daeSBarry Smith   PetscFunctionReturn(0);
2305c6c1daeSBarry Smith }
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith /*
2335c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
2345c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
2355c6c1daeSBarry Smith */
23695c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
2375c6c1daeSBarry Smith 
2385c6c1daeSBarry Smith /*@
2395c6c1daeSBarry Smith     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith     Input Parameters:
2441575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
2455c6c1daeSBarry Smith -    tabs - number of tabs
2465c6c1daeSBarry Smith 
2475c6c1daeSBarry Smith     Level: developer
2485c6c1daeSBarry Smith 
2495c6c1daeSBarry Smith     Fortran Note:
2505c6c1daeSBarry Smith     This routine is not supported in Fortran.
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
2535c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2545c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
2555c6c1daeSBarry Smith @*/
2565c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
2575c6c1daeSBarry Smith {
2585c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2595c6c1daeSBarry Smith   PetscBool         iascii;
2605c6c1daeSBarry Smith 
2615c6c1daeSBarry Smith   PetscFunctionBegin;
2625c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2639566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
264a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2655c6c1daeSBarry Smith   PetscFunctionReturn(0);
2665c6c1daeSBarry Smith }
2675c6c1daeSBarry Smith 
2685c6c1daeSBarry Smith /*@
2695c6c1daeSBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
2705c6c1daeSBarry Smith 
2715c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2725c6c1daeSBarry Smith 
2735c6c1daeSBarry Smith     Input Parameters:
2741575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
275a2b725a8SWilliam Gropp 
2765c6c1daeSBarry Smith     Output Parameters:
2775c6c1daeSBarry Smith .    tabs - number of tabs
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith     Level: developer
2805c6c1daeSBarry Smith 
2815c6c1daeSBarry Smith     Fortran Note:
2825c6c1daeSBarry Smith     This routine is not supported in Fortran.
2835c6c1daeSBarry Smith 
2845c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
2855c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2865c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
2875c6c1daeSBarry Smith @*/
2885c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
2895c6c1daeSBarry Smith {
2905c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2915c6c1daeSBarry Smith   PetscBool         iascii;
2925c6c1daeSBarry Smith 
2935c6c1daeSBarry Smith   PetscFunctionBegin;
2945c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
296a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
2975c6c1daeSBarry Smith   PetscFunctionReturn(0);
2985c6c1daeSBarry Smith }
2995c6c1daeSBarry Smith 
3005c6c1daeSBarry Smith /*@
3015c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
3025c6c1daeSBarry Smith 
3035c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3045c6c1daeSBarry Smith 
3055c6c1daeSBarry Smith     Input Parameters:
3061575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3075c6c1daeSBarry Smith -    tabs - number of tabs
3085c6c1daeSBarry Smith 
3095c6c1daeSBarry Smith     Level: developer
3105c6c1daeSBarry Smith 
3115c6c1daeSBarry Smith     Fortran Note:
3125c6c1daeSBarry Smith     This routine is not supported in Fortran.
3135c6c1daeSBarry Smith 
3145c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3155c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3165c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3175c6c1daeSBarry Smith @*/
3185c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
3195c6c1daeSBarry Smith {
3205c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3215c6c1daeSBarry Smith   PetscBool         iascii;
3225c6c1daeSBarry Smith 
3235c6c1daeSBarry Smith   PetscFunctionBegin;
3245c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
326a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3275c6c1daeSBarry Smith   PetscFunctionReturn(0);
3285c6c1daeSBarry Smith }
3295c6c1daeSBarry Smith 
3305c6c1daeSBarry Smith /*@
3315c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3325c6c1daeSBarry Smith 
3335c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3345c6c1daeSBarry Smith 
3355c6c1daeSBarry Smith     Input Parameters:
3361575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3375c6c1daeSBarry Smith -    tabs - number of tabs
3385c6c1daeSBarry Smith 
3395c6c1daeSBarry Smith     Level: developer
3405c6c1daeSBarry Smith 
3415c6c1daeSBarry Smith     Fortran Note:
3425c6c1daeSBarry Smith     This routine is not supported in Fortran.
3435c6c1daeSBarry Smith 
3445c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3455c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3465c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3475c6c1daeSBarry Smith @*/
3485c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
3495c6c1daeSBarry Smith {
3505c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3515c6c1daeSBarry Smith   PetscBool         iascii;
3525c6c1daeSBarry Smith 
3535c6c1daeSBarry Smith   PetscFunctionBegin;
3545c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
356a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3575c6c1daeSBarry Smith   PetscFunctionReturn(0);
3585c6c1daeSBarry Smith }
3595c6c1daeSBarry Smith 
3605c6c1daeSBarry Smith /*@C
3611575c14dSBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
3625c6c1daeSBarry Smith 
3635c6c1daeSBarry Smith     Collective on PetscViewer
3645c6c1daeSBarry Smith 
3655c6c1daeSBarry Smith     Input Parameters:
3661575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith     Level: intermediate
3695c6c1daeSBarry Smith 
370e6abc3ddSVáclav Hapla     Notes:
371e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
3725c6c1daeSBarry Smith 
373e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
374e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
375e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
3765c6c1daeSBarry Smith @*/
3771575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
3785c6c1daeSBarry Smith {
3795c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3805c6c1daeSBarry Smith   PetscBool         iascii;
3815c6c1daeSBarry Smith 
3825c6c1daeSBarry Smith   PetscFunctionBegin;
3835c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
38428b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3859566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
3861575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3871575c14dSBarry Smith   PetscFunctionReturn(0);
3881575c14dSBarry Smith }
3891575c14dSBarry Smith 
3901575c14dSBarry Smith /*@C
3911575c14dSBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
3921575c14dSBarry Smith 
3931575c14dSBarry Smith     Collective on PetscViewer
3941575c14dSBarry Smith 
3951575c14dSBarry Smith     Input Parameters:
3961575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3971575c14dSBarry Smith 
3981575c14dSBarry Smith     Level: intermediate
3991575c14dSBarry Smith 
400e6abc3ddSVáclav Hapla     Notes:
401e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
4021575c14dSBarry Smith 
403e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
404e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
405e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
4061575c14dSBarry Smith @*/
4071575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
4081575c14dSBarry Smith {
4091575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4101575c14dSBarry Smith   PetscBool         iascii;
4111575c14dSBarry Smith 
4121575c14dSBarry Smith   PetscFunctionBegin;
4131575c14dSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
41428b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
4159566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
4161575c14dSBarry Smith   if (iascii) {
4171575c14dSBarry Smith     ascii->allowsynchronized--;
4182c71b3e2SJacob Faibussowitsch     PetscCheckFalse(ascii->allowsynchronized < 0,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
4191575c14dSBarry Smith   }
4205c6c1daeSBarry Smith   PetscFunctionReturn(0);
4215c6c1daeSBarry Smith }
4225c6c1daeSBarry Smith 
4231c297824SMatthew G. Knepley /*@C
4245c6c1daeSBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
4255c6c1daeSBarry Smith      lines are tabbed.
4265c6c1daeSBarry Smith 
4275c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4285c6c1daeSBarry Smith 
4295c6c1daeSBarry Smith     Input Parameters:
4301575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4315c6c1daeSBarry Smith 
4325c6c1daeSBarry Smith     Level: developer
4335c6c1daeSBarry Smith 
4345c6c1daeSBarry Smith     Fortran Note:
4355c6c1daeSBarry Smith     This routine is not supported in Fortran.
4365c6c1daeSBarry Smith 
4375c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4385c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4395c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4405c6c1daeSBarry Smith @*/
4415c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
4425c6c1daeSBarry Smith {
4435c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4445c6c1daeSBarry Smith   PetscBool         iascii;
4455c6c1daeSBarry Smith 
4465c6c1daeSBarry Smith   PetscFunctionBegin;
4475c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4489566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
449a297a907SKarl Rupp   if (iascii) ascii->tab++;
4505c6c1daeSBarry Smith   PetscFunctionReturn(0);
4515c6c1daeSBarry Smith }
4525c6c1daeSBarry Smith 
4531c297824SMatthew G. Knepley /*@C
4545c6c1daeSBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
4555c6c1daeSBarry Smith      lines are tabbed.
4565c6c1daeSBarry Smith 
4575c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4585c6c1daeSBarry Smith 
4595c6c1daeSBarry Smith     Input Parameters:
4601575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4615c6c1daeSBarry Smith 
4625c6c1daeSBarry Smith     Level: developer
4635c6c1daeSBarry Smith 
4645c6c1daeSBarry Smith     Fortran Note:
4655c6c1daeSBarry Smith     This routine is not supported in Fortran.
4665c6c1daeSBarry Smith 
4675c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4685c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4695c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4705c6c1daeSBarry Smith @*/
4715c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
4725c6c1daeSBarry Smith {
4735c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4745c6c1daeSBarry Smith   PetscBool         iascii;
4755c6c1daeSBarry Smith 
4765c6c1daeSBarry Smith   PetscFunctionBegin;
4775c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4789566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
4795c6c1daeSBarry Smith   if (iascii) {
4802c71b3e2SJacob Faibussowitsch     PetscCheckFalse(ascii->tab <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
4815c6c1daeSBarry Smith     ascii->tab--;
4825c6c1daeSBarry Smith   }
4835c6c1daeSBarry Smith   PetscFunctionReturn(0);
4845c6c1daeSBarry Smith }
4855c6c1daeSBarry Smith 
4865c6c1daeSBarry Smith /*@
4875c6c1daeSBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
4885c6c1daeSBarry Smith 
4895c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4905c6c1daeSBarry Smith 
4915c6c1daeSBarry Smith     Input Parameters:
4921575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
4935c6c1daeSBarry Smith -    flg - PETSC_TRUE or PETSC_FALSE
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith     Level: developer
4965c6c1daeSBarry Smith 
4975c6c1daeSBarry Smith     Fortran Note:
4985c6c1daeSBarry Smith     This routine is not supported in Fortran.
4995c6c1daeSBarry Smith 
5005c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
5015c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
5025c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
5035c6c1daeSBarry Smith @*/
5045c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
5055c6c1daeSBarry Smith {
5065c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5075c6c1daeSBarry Smith   PetscBool         iascii;
5085c6c1daeSBarry Smith 
5095c6c1daeSBarry Smith   PetscFunctionBegin;
5105c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
5119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
5125c6c1daeSBarry Smith   if (iascii) {
513a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
514a297a907SKarl Rupp     else {
5155c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
5165c6c1daeSBarry Smith       ascii->tab       = 0;
5175c6c1daeSBarry Smith     }
5185c6c1daeSBarry Smith   }
5195c6c1daeSBarry Smith   PetscFunctionReturn(0);
5205c6c1daeSBarry Smith }
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5235c6c1daeSBarry Smith 
5245c6c1daeSBarry Smith /*@C
5255c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5265c6c1daeSBarry Smith     processor in the PetscViewer
5275c6c1daeSBarry Smith 
5285c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5295c6c1daeSBarry Smith 
5305c6c1daeSBarry Smith     Input Parameters:
5311575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5325c6c1daeSBarry Smith -    format - the usual printf() format string
5335c6c1daeSBarry Smith 
5345c6c1daeSBarry Smith     Level: developer
5355c6c1daeSBarry Smith 
5365c6c1daeSBarry Smith     Fortran Note:
5375c6c1daeSBarry Smith     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
5385c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5395c6c1daeSBarry Smith 
5405c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
5415c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
5421575c14dSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
5435c6c1daeSBarry Smith @*/
5445c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
5455c6c1daeSBarry Smith {
5465c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5475c6c1daeSBarry Smith   PetscMPIInt       rank;
548dd2fa690SBarry Smith   PetscInt          tab,intab = ascii->tab;
5495c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5503f08860eSBarry Smith   PetscBool         iascii;
5515c6c1daeSBarry Smith   int               err;
5525c6c1daeSBarry Smith 
5535c6c1daeSBarry Smith   PetscFunctionBegin;
5545c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
55528b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5565c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
5579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
55828b400f6SJacob Faibussowitsch   PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
5599566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
560559f443fSBarry Smith   if (rank) PetscFunctionReturn(0);
5613f08860eSBarry Smith 
5623f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5633f08860eSBarry Smith     char        *string;
5643f08860eSBarry Smith     va_list     Argp;
5653f08860eSBarry Smith     size_t      fullLength;
5663f08860eSBarry Smith 
5679566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5683f08860eSBarry Smith     va_start(Argp,format);
5699566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp));
5703f08860eSBarry Smith     va_end(Argp);
5719566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer,"%s",string));
5729566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5733f08860eSBarry Smith   } else { /* write directly to file */
5745c6c1daeSBarry Smith     va_list Argp;
575559f443fSBarry Smith     /* flush my own messages that I may have queued up */
576559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
577559f443fSBarry Smith     PetscInt    i;
578559f443fSBarry Smith     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
5799566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string));
580559f443fSBarry Smith       previous = next;
581559f443fSBarry Smith       next     = next->next;
5829566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5839566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
584559f443fSBarry Smith     }
58502c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
586559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
587dd2fa690SBarry Smith     tab = intab;
588a297a907SKarl Rupp     while (tab--) {
5899566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd,"  "));
590a297a907SKarl Rupp     }
5915c6c1daeSBarry Smith 
5925c6c1daeSBarry Smith     va_start(Argp,format);
5939566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd,format,Argp));
5945c6c1daeSBarry Smith     err  = fflush(fd);
59528b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
5965c6c1daeSBarry Smith     if (petsc_history) {
5975c6c1daeSBarry Smith       va_start(Argp,format);
598dd2fa690SBarry Smith       tab = intab;
599a297a907SKarl Rupp       while (tab--) {
6009566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  "));
601a297a907SKarl Rupp       }
6029566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history,format,Argp));
6035c6c1daeSBarry Smith       err  = fflush(petsc_history);
60428b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6055c6c1daeSBarry Smith     }
6065c6c1daeSBarry Smith     va_end(Argp);
6075c6c1daeSBarry Smith   }
6085c6c1daeSBarry Smith   PetscFunctionReturn(0);
6095c6c1daeSBarry Smith }
6105c6c1daeSBarry Smith 
6115c6c1daeSBarry Smith /*@C
6125c6c1daeSBarry Smith      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
6135c6c1daeSBarry Smith 
6145c6c1daeSBarry Smith     Collective on PetscViewer
6155c6c1daeSBarry Smith 
6165c6c1daeSBarry Smith   Input Parameters:
6175c6c1daeSBarry Smith +  viewer - the PetscViewer; either ASCII or binary
6185c6c1daeSBarry Smith -  name - the name of the file it should use
6195c6c1daeSBarry Smith 
6205c6c1daeSBarry Smith     Level: advanced
6215c6c1daeSBarry Smith 
6225c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
6235c6c1daeSBarry Smith           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
6245c6c1daeSBarry Smith 
6255c6c1daeSBarry Smith @*/
6265c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
6275c6c1daeSBarry Smith {
628cc843e7aSLisandro Dalcin   char           filename[PETSC_MAX_PATH_LEN];
6295c6c1daeSBarry Smith 
6305c6c1daeSBarry Smith   PetscFunctionBegin;
6315c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6325c6c1daeSBarry Smith   PetscValidCharPointer(name,2);
6339566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename)));
634*cac4c232SBarry Smith   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
6355c6c1daeSBarry Smith   PetscFunctionReturn(0);
6365c6c1daeSBarry Smith }
6375c6c1daeSBarry Smith 
6385c6c1daeSBarry Smith /*@C
6395c6c1daeSBarry Smith      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
6405c6c1daeSBarry Smith 
6415c6c1daeSBarry Smith     Not Collective
6425c6c1daeSBarry Smith 
6435c6c1daeSBarry Smith   Input Parameter:
6445c6c1daeSBarry Smith .  viewer - the PetscViewer; either ASCII or binary
6455c6c1daeSBarry Smith 
6465c6c1daeSBarry Smith   Output Parameter:
6475c6c1daeSBarry Smith .  name - the name of the file it is using
6485c6c1daeSBarry Smith 
6495c6c1daeSBarry Smith     Level: advanced
6505c6c1daeSBarry Smith 
6515c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
6525c6c1daeSBarry Smith 
6535c6c1daeSBarry Smith @*/
6545c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
6555c6c1daeSBarry Smith {
6565c6c1daeSBarry Smith   PetscFunctionBegin;
6575c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6586e05b1faSLisandro Dalcin   PetscValidPointer(name,2);
659*cac4c232SBarry Smith   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
6605c6c1daeSBarry Smith   PetscFunctionReturn(0);
6615c6c1daeSBarry Smith }
6625c6c1daeSBarry Smith 
6635c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
6645c6c1daeSBarry Smith {
6655c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6665c6c1daeSBarry Smith 
6675c6c1daeSBarry Smith   PetscFunctionBegin;
6685c6c1daeSBarry Smith   *name = vascii->filename;
6695c6c1daeSBarry Smith   PetscFunctionReturn(0);
6705c6c1daeSBarry Smith }
6715c6c1daeSBarry Smith 
6725c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
6735c6c1daeSBarry Smith {
6745c6c1daeSBarry Smith   size_t            len;
6755c6c1daeSBarry Smith   char              fname[PETSC_MAX_PATH_LEN],*gz;
6765c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6775c6c1daeSBarry Smith   PetscBool         isstderr,isstdout;
6785c6c1daeSBarry Smith   PetscMPIInt       rank;
6795c6c1daeSBarry Smith 
6805c6c1daeSBarry Smith   PetscFunctionBegin;
6819566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6825c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
6839566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&vascii->filename));
6845c6c1daeSBarry Smith 
6855c6c1daeSBarry Smith   /* Is this file to be compressed */
6865c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
687a297a907SKarl Rupp 
6889566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename,".gz",&gz));
6895c6c1daeSBarry Smith   if (gz) {
6909566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz,&len));
6915c6c1daeSBarry Smith     if (len == 3) {
6922c71b3e2SJacob Faibussowitsch       PetscCheckFalse(vascii->mode != FILE_MODE_WRITE,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
6935c6c1daeSBarry Smith       *gz = 0;
6945c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6955c6c1daeSBarry Smith     }
6965c6c1daeSBarry Smith   }
6979566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
698dd400576SPatrick Sanan   if (rank == 0) {
6999566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name,"stderr",&isstderr));
7009566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name,"stdout",&isstdout));
7015c6c1daeSBarry Smith     /* empty filename means stdout */
7025c6c1daeSBarry Smith     if (name[0] == 0)  isstdout = PETSC_TRUE;
7035c6c1daeSBarry Smith     if (isstderr)      vascii->fd = PETSC_STDERR;
7045c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
7055c6c1daeSBarry Smith     else {
7065c6c1daeSBarry Smith 
7079566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name,fname));
7085c6c1daeSBarry Smith       switch (vascii->mode) {
7095c6c1daeSBarry Smith       case FILE_MODE_READ:
7105c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r");
7115c6c1daeSBarry Smith         break;
7125c6c1daeSBarry Smith       case FILE_MODE_WRITE:
7135c6c1daeSBarry Smith         vascii->fd = fopen(fname,"w");
7145c6c1daeSBarry Smith         break;
7155c6c1daeSBarry Smith       case FILE_MODE_APPEND:
7165c6c1daeSBarry Smith         vascii->fd = fopen(fname,"a");
7175c6c1daeSBarry Smith         break;
7185c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
7195c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
720a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
7215c6c1daeSBarry Smith         break;
7225c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
7235c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
7245c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
7255c6c1daeSBarry Smith         */
7265c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
727a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
728a297a907SKarl Rupp         else {
7299566063dSJacob Faibussowitsch           PetscCall(fseek(vascii->fd, 0, SEEK_END));
7305c6c1daeSBarry Smith         }
7315c6c1daeSBarry Smith         break;
7325c6c1daeSBarry Smith       default:
73398921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
7345c6c1daeSBarry Smith       }
73528b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
7365c6c1daeSBarry Smith     }
7375c6c1daeSBarry Smith   }
7385c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7395c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
7405c6c1daeSBarry Smith #endif
7415c6c1daeSBarry Smith   PetscFunctionReturn(0);
7425c6c1daeSBarry Smith }
7435c6c1daeSBarry Smith 
7443f08860eSBarry Smith PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
7455c6c1daeSBarry Smith {
7465c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
7475c6c1daeSBarry Smith 
7485c6c1daeSBarry Smith   PetscFunctionBegin;
7499566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
75028b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
751e5afcf28SBarry Smith   /*
7529530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7539530cbd7SBarry Smith      because it relies on this behavior in other places. In particular this line causes the synchronized flush to occur when the viewer is destroyed
7549530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7559530cbd7SBarry Smith 
7569530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7579530cbd7SBarry Smith      PCView_GASM().
758e5afcf28SBarry Smith   */
7599566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7609566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm,outviewer));
7619566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer,PETSCVIEWERASCII));
7629566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7635c6c1daeSBarry Smith   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
7645c6c1daeSBarry Smith   ovascii->fd  = vascii->fd;
7655c6c1daeSBarry Smith   ovascii->tab = vascii->tab;
766ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7675c6c1daeSBarry Smith 
7685c6c1daeSBarry Smith   vascii->sviewer = *outviewer;
7695c6c1daeSBarry Smith   (*outviewer)->format  = viewer->format;
7705c6c1daeSBarry Smith   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
7713f08860eSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
7725c6c1daeSBarry Smith   PetscFunctionReturn(0);
7735c6c1daeSBarry Smith }
7745c6c1daeSBarry Smith 
7753f08860eSBarry Smith PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
7765c6c1daeSBarry Smith {
7775c6c1daeSBarry Smith   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
7785c6c1daeSBarry Smith 
7795c6c1daeSBarry Smith   PetscFunctionBegin;
78028b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
7812c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ascii->sviewer != *outviewer,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
7825c6c1daeSBarry Smith 
7839566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
784e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7855c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7869566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7879566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7885c6c1daeSBarry Smith   PetscFunctionReturn(0);
7895c6c1daeSBarry Smith }
7905c6c1daeSBarry Smith 
7912bf49c77SBarry Smith PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
7922bf49c77SBarry Smith {
7932bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
7942bf49c77SBarry Smith 
7952bf49c77SBarry Smith   PetscFunctionBegin;
7962bf49c77SBarry Smith   if (ascii->filename) {
7979566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename));
7982bf49c77SBarry Smith   }
7992bf49c77SBarry Smith   PetscFunctionReturn(0);
8002bf49c77SBarry Smith }
8012bf49c77SBarry Smith 
8028556b5ebSBarry Smith /*MC
8038556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
8048556b5ebSBarry Smith 
8058556b5ebSBarry Smith .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
8068556b5ebSBarry Smith            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
8078556b5ebSBarry Smith            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
8088556b5ebSBarry Smith 
8091b266c99SBarry Smith   Level: beginner
8101b266c99SBarry Smith 
8118556b5ebSBarry Smith M*/
8128cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
8135c6c1daeSBarry Smith {
8145c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
8155c6c1daeSBarry Smith 
8165c6c1daeSBarry Smith   PetscFunctionBegin;
8179566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(viewer,&vascii));
8185c6c1daeSBarry Smith   viewer->data = (void*)vascii;
8195c6c1daeSBarry Smith 
8205c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
8215c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
822559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
823559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
8242bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
8251d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
8265c6c1daeSBarry Smith 
8275c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
8285c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
8295c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
83002c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
83102c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
83202c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
8335c6c1daeSBarry Smith   vascii->tab       = 0;
8345c6c1daeSBarry Smith   vascii->tab_store = 0;
83502c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
8365c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8375c6c1daeSBarry Smith 
8389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII));
8399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII));
8409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII));
8419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII));
8425c6c1daeSBarry Smith   PetscFunctionReturn(0);
8435c6c1daeSBarry Smith }
8445c6c1daeSBarry Smith 
8455c6c1daeSBarry Smith /*@C
8465c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8475c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8485c6c1daeSBarry Smith     second, etc.
8495c6c1daeSBarry Smith 
8505c6c1daeSBarry Smith     Not Collective, must call collective PetscViewerFlush() to get the results out
8515c6c1daeSBarry Smith 
8525c6c1daeSBarry Smith     Input Parameters:
8535c6c1daeSBarry Smith +   viewer - the ASCII PetscViewer
8545c6c1daeSBarry Smith -   format - the usual printf() format string
8555c6c1daeSBarry Smith 
8565c6c1daeSBarry Smith     Level: intermediate
8575c6c1daeSBarry Smith 
85895452b02SPatrick Sanan     Notes:
859e6abc3ddSVáclav Hapla     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
860e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
861e6abc3ddSVáclav Hapla     The actual synchronized print is then done using PetscViewerFlush().
862e6abc3ddSVáclav Hapla     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
863e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
864e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
865e6abc3ddSVáclav Hapla $ PetscViewerASCIIPushSynchronized(viewer);
866e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
867e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
868e6abc3ddSVáclav Hapla $ ...
869e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
870e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
871e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
872e6abc3ddSVáclav Hapla $ ...
873e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
874e6abc3ddSVáclav Hapla $ PetscViewerASCIIPopSynchronized(viewer);
8755c6c1daeSBarry Smith 
8765c6c1daeSBarry Smith     Fortran Note:
8775c6c1daeSBarry Smith       Can only print a single character* string
8785c6c1daeSBarry Smith 
879e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
880e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
881e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
8825c6c1daeSBarry Smith @*/
8835c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
8845c6c1daeSBarry Smith {
8855c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
8863f08860eSBarry Smith   PetscMPIInt       rank;
8875c6c1daeSBarry Smith   PetscInt          tab = vascii->tab;
8885c6c1daeSBarry Smith   MPI_Comm          comm;
8895c6c1daeSBarry Smith   FILE              *fp;
890559f443fSBarry Smith   PetscBool         iascii,hasbviewer = PETSC_FALSE;
8915c6c1daeSBarry Smith   int               err;
8925c6c1daeSBarry Smith 
8935c6c1daeSBarry Smith   PetscFunctionBegin;
8945c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
8955c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
8969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
89728b400f6SJacob Faibussowitsch   PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
89828b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
8995c6c1daeSBarry Smith 
9009566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
9019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
9025c6c1daeSBarry Smith 
903559f443fSBarry Smith   if (vascii->bviewer) {
904559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
905dd400576SPatrick Sanan     if (rank == 0) {
906559f443fSBarry Smith       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
9079566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
9089566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm,&rank));
909559f443fSBarry Smith     }
910559f443fSBarry Smith   }
9113f08860eSBarry Smith 
912559f443fSBarry Smith   fp   = vascii->fd;
913559f443fSBarry Smith 
914dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
9155c6c1daeSBarry Smith     va_list Argp;
916559f443fSBarry Smith     /* flush my own messages that I may have queued up */
917559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
918559f443fSBarry Smith     PetscInt    i;
919559f443fSBarry Smith     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
9209566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm,fp,"%s",next->string));
921559f443fSBarry Smith       previous = next;
922559f443fSBarry Smith       next     = next->next;
9239566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
9249566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
925559f443fSBarry Smith     }
92602c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
927559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
9285c6c1daeSBarry Smith 
929a297a907SKarl Rupp     while (tab--) {
9309566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fp,"  "));
931a297a907SKarl Rupp     }
9325c6c1daeSBarry Smith 
9335c6c1daeSBarry Smith     va_start(Argp,format);
9349566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp,format,Argp));
9355c6c1daeSBarry Smith     err  = fflush(fp);
93628b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9375c6c1daeSBarry Smith     if (petsc_history) {
9385c6c1daeSBarry Smith       va_start(Argp,format);
9399566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history,format,Argp));
9405c6c1daeSBarry Smith       err  = fflush(petsc_history);
94128b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9425c6c1daeSBarry Smith     }
9435c6c1daeSBarry Smith     va_end(Argp);
944559f443fSBarry Smith   } else { /* other processors add to queue */
9455c6c1daeSBarry Smith     char        *string;
9465c6c1daeSBarry Smith     va_list     Argp;
9475c6c1daeSBarry Smith     size_t      fullLength;
9485c6c1daeSBarry Smith     PrintfQueue next;
9495c6c1daeSBarry Smith 
9509566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
951559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
952559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
953559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
954a297a907SKarl Rupp     } else {
955559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
956a297a907SKarl Rupp     }
957559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9585c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9599566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9605c6c1daeSBarry Smith     string     = next->string;
9615c6c1daeSBarry Smith     tab       *= 2;
962a297a907SKarl Rupp     while (tab--) {
963a297a907SKarl Rupp       *string++ = ' ';
964a297a907SKarl Rupp     }
9655c6c1daeSBarry Smith     va_start(Argp,format);
9669566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp));
9675c6c1daeSBarry Smith     va_end(Argp);
968cb500232SBarry Smith     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
9699566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
97014416c0eSBarry Smith       next->size = fullLength + 2*vascii->tab;
9719566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
97214416c0eSBarry Smith       string     = next->string;
97314416c0eSBarry Smith       tab        = 2*vascii->tab;
97414416c0eSBarry Smith       while (tab--) {
97514416c0eSBarry Smith         *string++ = ' ';
97614416c0eSBarry Smith       }
97714416c0eSBarry Smith       va_start(Argp,format);
9789566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp));
97914416c0eSBarry Smith       va_end(Argp);
98014416c0eSBarry Smith     }
9815c6c1daeSBarry Smith   }
9825c6c1daeSBarry Smith   PetscFunctionReturn(0);
9835c6c1daeSBarry Smith }
9845c6c1daeSBarry Smith 
9852655f987SMichael Lange /*@C
986f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9872655f987SMichael Lange 
988f8859db6SBarry Smith    Only process 0 in the PetscViewer may call this
9892655f987SMichael Lange 
9902655f987SMichael Lange    Input Parameters:
9912655f987SMichael Lange +  viewer - the ascii viewer
9922655f987SMichael Lange .  data - location to write the data
993060da220SMatthew G. Knepley .  num - number of items of data to read
9942655f987SMichael Lange -  datatype - type of data to read
9952655f987SMichael Lange 
996f8e4bde8SMatthew G. Knepley    Output Parameters:
997060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
998f8e4bde8SMatthew G. Knepley 
9992655f987SMichael Lange    Level: beginner
10002655f987SMichael Lange 
1001f8859db6SBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
10022655f987SMichael Lange           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
100305119932SBarry Smith           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
10042655f987SMichael Lange @*/
1005060da220SMatthew G. Knepley PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
10062655f987SMichael Lange {
10072655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
10082655f987SMichael Lange   FILE              *fd = vascii->fd;
10092655f987SMichael Lange   PetscInt           i;
10103b7fe8c3SMatthew G. Knepley   int                ret = 0;
1011f8859db6SBarry Smith   PetscMPIInt        rank;
10122655f987SMichael Lange 
10132655f987SMichael Lange   PetscFunctionBegin;
10142655f987SMichael Lange   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
10159566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
101628b400f6SJacob Faibussowitsch   PetscCheck(!rank,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1017060da220SMatthew G. Knepley   for (i=0; i<num; i++) {
1018f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1019f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1020a05e1a72SSatish Balay     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1021f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
10229e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1023972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1024f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1025f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1026a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
1027fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
1028fba955ccSBarry Smith       double tmp;
1029fba955ccSBarry Smith       ret = fscanf(fd, "%lg", &tmp);
1030a6e181c6SToby Isaac       ((__float128*)data)[i] = tmp;
1031a6e181c6SToby Isaac     }
1032fba955ccSBarry Smith #endif
103398921bdaSJacob Faibussowitsch     else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
103428b400f6SJacob Faibussowitsch     PetscCheck(ret,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1035f8e4bde8SMatthew G. Knepley     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10362655f987SMichael Lange   }
1037060da220SMatthew G. Knepley   if (count) *count = i;
10382c71b3e2SJacob Faibussowitsch   else PetscCheckFalse(ret < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
10392655f987SMichael Lange   PetscFunctionReturn(0);
10402655f987SMichael Lange }
1041