xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 2e956fe4fc852fabc23b437482e1fb7b77fddb0d)
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));
27cc73adaaSBarry Smith       PetscCheck(!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   }
90*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",NULL));
91*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",NULL));
92*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",NULL));
93*2e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",NULL));
945c6c1daeSBarry Smith   PetscFunctionReturn(0);
955c6c1daeSBarry Smith }
965c6c1daeSBarry Smith 
973f08860eSBarry Smith PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
985c6c1daeSBarry Smith {
995c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1005fd66863SKarl Rupp 
1015c6c1daeSBarry Smith   PetscFunctionBegin;
1029566063dSJacob Faibussowitsch   PetscCall(PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer));
1035c6c1daeSBarry Smith   PetscFunctionReturn(0);
1045c6c1daeSBarry Smith }
1055c6c1daeSBarry Smith 
1065c6c1daeSBarry Smith PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
1075c6c1daeSBarry Smith {
1085c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1095c6c1daeSBarry Smith   int               err;
110559f443fSBarry Smith   MPI_Comm          comm;
111559f443fSBarry Smith   PetscMPIInt       rank,size;
112559f443fSBarry Smith   FILE              *fd = vascii->fd;
1135c6c1daeSBarry Smith 
1145c6c1daeSBarry Smith   PetscFunctionBegin;
11528b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
1169566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
1179566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
1189566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
119559f443fSBarry Smith 
120dd400576SPatrick Sanan   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
1215c6c1daeSBarry Smith     err = fflush(vascii->fd);
12228b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
1235c6c1daeSBarry Smith   }
1245c6c1daeSBarry Smith 
1255c6c1daeSBarry Smith   if (vascii->allowsynchronized) {
126559f443fSBarry Smith     PetscMPIInt   tag,i,j,n = 0,dummy = 0;
127559f443fSBarry Smith     char          *message;
128559f443fSBarry Smith     MPI_Status    status;
129559f443fSBarry Smith 
1309566063dSJacob Faibussowitsch     PetscCall(PetscCommDuplicate(comm,&comm,&tag));
131559f443fSBarry Smith 
132559f443fSBarry Smith     /* First processor waits for messages from all other processors */
133dd400576SPatrick Sanan     if (rank == 0) {
134559f443fSBarry Smith       /* flush my own messages that I may have queued up */
135559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
136559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
137559f443fSBarry Smith         if (!vascii->bviewer) {
1389566063dSJacob Faibussowitsch           PetscCall(PetscFPrintf(comm,fd,"%s",next->string));
139559f443fSBarry Smith         } else {
1409566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string));
141559f443fSBarry Smith         }
142559f443fSBarry Smith         previous = next;
143559f443fSBarry Smith         next     = next->next;
1449566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1459566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
146559f443fSBarry Smith       }
14702c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
148559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
149559f443fSBarry Smith       for (i=1; i<size; i++) {
150559f443fSBarry Smith         /* to prevent a flood of messages to process zero, request each message separately */
1519566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&dummy,1,MPI_INT,i,tag,comm));
1529566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status));
153559f443fSBarry Smith         for (j=0; j<n; j++) {
154559f443fSBarry Smith           PetscMPIInt size = 0;
155559f443fSBarry Smith 
1569566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status));
1579566063dSJacob Faibussowitsch           PetscCall(PetscMalloc1(size, &message));
1589566063dSJacob Faibussowitsch           PetscCallMPI(MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status));
159559f443fSBarry Smith           if (!vascii->bviewer) {
1609566063dSJacob Faibussowitsch             PetscCall(PetscFPrintf(comm,fd,"%s",message));
161559f443fSBarry Smith           } else {
1629566063dSJacob Faibussowitsch             PetscCall(PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message));
163559f443fSBarry Smith           }
1649566063dSJacob Faibussowitsch           PetscCall(PetscFree(message));
165559f443fSBarry Smith         }
166559f443fSBarry Smith       }
167559f443fSBarry Smith     } else { /* other processors send queue to processor 0 */
168559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
169559f443fSBarry Smith 
1709566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status));
1719566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm));
172559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
1739566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(&next->size,1,MPI_INT,0,tag,comm));
1749566063dSJacob Faibussowitsch         PetscCallMPI(MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm));
175559f443fSBarry Smith         previous = next;
176559f443fSBarry Smith         next     = next->next;
1779566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous->string));
1789566063dSJacob Faibussowitsch         PetscCall(PetscFree(previous));
179559f443fSBarry Smith       }
18002c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
181559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
182559f443fSBarry Smith     }
1839566063dSJacob Faibussowitsch     PetscCall(PetscCommDestroy(&comm));
1845c6c1daeSBarry Smith   }
1855c6c1daeSBarry Smith   PetscFunctionReturn(0);
1865c6c1daeSBarry Smith }
1875c6c1daeSBarry Smith 
1885c6c1daeSBarry Smith /*@C
1895c6c1daeSBarry Smith     PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
1905c6c1daeSBarry Smith 
191f8859db6SBarry Smith     Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
1925c6c1daeSBarry Smith 
193f8859db6SBarry Smith     Input Parameter:
194f8859db6SBarry Smith .    viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
195f8859db6SBarry Smith 
196f8859db6SBarry Smith     Output Parameter:
197f8859db6SBarry Smith .    fd - file pointer
198f8859db6SBarry Smith 
199f8859db6SBarry Smith     Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
2005c6c1daeSBarry Smith 
2015c6c1daeSBarry Smith     Level: intermediate
2025c6c1daeSBarry Smith 
2035c6c1daeSBarry Smith     Fortran Note:
2045c6c1daeSBarry Smith     This routine is not supported in Fortran.
2055c6c1daeSBarry Smith 
206db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerCreate()`, `PetscViewerASCIIPrintf()`,
207db781477SPatrick Sanan           `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`
2085c6c1daeSBarry Smith @*/
2095c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
2105c6c1daeSBarry Smith {
2115c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2125c6c1daeSBarry Smith 
2135c6c1daeSBarry Smith   PetscFunctionBegin;
2145c6c1daeSBarry Smith   *fd = vascii->fd;
2155c6c1daeSBarry Smith   PetscFunctionReturn(0);
2165c6c1daeSBarry Smith }
2175c6c1daeSBarry Smith 
2185c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
2195c6c1daeSBarry Smith {
2205c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2215c6c1daeSBarry Smith 
2225c6c1daeSBarry Smith   PetscFunctionBegin;
2235c6c1daeSBarry Smith   *mode = vascii->mode;
2245c6c1daeSBarry Smith   PetscFunctionReturn(0);
2255c6c1daeSBarry Smith }
2265c6c1daeSBarry Smith 
2275c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
2285c6c1daeSBarry Smith {
2295c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2305c6c1daeSBarry Smith 
2315c6c1daeSBarry Smith   PetscFunctionBegin;
2325c6c1daeSBarry Smith   vascii->mode = mode;
2335c6c1daeSBarry Smith   PetscFunctionReturn(0);
2345c6c1daeSBarry Smith }
2355c6c1daeSBarry Smith 
2365c6c1daeSBarry Smith /*
2375c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
2385c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
2395c6c1daeSBarry Smith */
24095c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
2415c6c1daeSBarry Smith 
2425c6c1daeSBarry Smith /*@
2435c6c1daeSBarry Smith     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
2445c6c1daeSBarry Smith 
2455c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
2465c6c1daeSBarry Smith 
2475c6c1daeSBarry Smith     Input Parameters:
2481575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
2495c6c1daeSBarry Smith -    tabs - number of tabs
2505c6c1daeSBarry Smith 
2515c6c1daeSBarry Smith     Level: developer
2525c6c1daeSBarry Smith 
2535c6c1daeSBarry Smith     Fortran Note:
2545c6c1daeSBarry Smith     This routine is not supported in Fortran.
2555c6c1daeSBarry Smith 
256db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIGetTab()`,
257db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
258db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2595c6c1daeSBarry Smith @*/
2605c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
2615c6c1daeSBarry Smith {
2625c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2635c6c1daeSBarry Smith   PetscBool         iascii;
2645c6c1daeSBarry Smith 
2655c6c1daeSBarry Smith   PetscFunctionBegin;
2665c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
268a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2695c6c1daeSBarry Smith   PetscFunctionReturn(0);
2705c6c1daeSBarry Smith }
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith /*@
2735c6c1daeSBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
2745c6c1daeSBarry Smith 
2755c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2765c6c1daeSBarry Smith 
2775c6c1daeSBarry Smith     Input Parameters:
2781575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
279a2b725a8SWilliam Gropp 
2805c6c1daeSBarry Smith     Output Parameters:
2815c6c1daeSBarry Smith .    tabs - number of tabs
2825c6c1daeSBarry Smith 
2835c6c1daeSBarry Smith     Level: developer
2845c6c1daeSBarry Smith 
2855c6c1daeSBarry Smith     Fortran Note:
2865c6c1daeSBarry Smith     This routine is not supported in Fortran.
2875c6c1daeSBarry Smith 
288db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISetTab()`,
289db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
290db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
2915c6c1daeSBarry Smith @*/
2925c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
2935c6c1daeSBarry Smith {
2945c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2955c6c1daeSBarry Smith   PetscBool         iascii;
2965c6c1daeSBarry Smith 
2975c6c1daeSBarry Smith   PetscFunctionBegin;
2985c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2999566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
300a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
3015c6c1daeSBarry Smith   PetscFunctionReturn(0);
3025c6c1daeSBarry Smith }
3035c6c1daeSBarry Smith 
3045c6c1daeSBarry Smith /*@
3055c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
3065c6c1daeSBarry Smith 
3075c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3085c6c1daeSBarry Smith 
3095c6c1daeSBarry Smith     Input Parameters:
3101575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3115c6c1daeSBarry Smith -    tabs - number of tabs
3125c6c1daeSBarry Smith 
3135c6c1daeSBarry Smith     Level: developer
3145c6c1daeSBarry Smith 
3155c6c1daeSBarry Smith     Fortran Note:
3165c6c1daeSBarry Smith     This routine is not supported in Fortran.
3175c6c1daeSBarry Smith 
318db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
319db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
320db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3215c6c1daeSBarry Smith @*/
3225c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
3235c6c1daeSBarry Smith {
3245c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3255c6c1daeSBarry Smith   PetscBool         iascii;
3265c6c1daeSBarry Smith 
3275c6c1daeSBarry Smith   PetscFunctionBegin;
3285c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
330a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3315c6c1daeSBarry Smith   PetscFunctionReturn(0);
3325c6c1daeSBarry Smith }
3335c6c1daeSBarry Smith 
3345c6c1daeSBarry Smith /*@
3355c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3385c6c1daeSBarry Smith 
3395c6c1daeSBarry Smith     Input Parameters:
3401575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3415c6c1daeSBarry Smith -    tabs - number of tabs
3425c6c1daeSBarry Smith 
3435c6c1daeSBarry Smith     Level: developer
3445c6c1daeSBarry Smith 
3455c6c1daeSBarry Smith     Fortran Note:
3465c6c1daeSBarry Smith     This routine is not supported in Fortran.
3475c6c1daeSBarry Smith 
348db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
349db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
350db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushTab()`
3515c6c1daeSBarry Smith @*/
3525c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
3535c6c1daeSBarry Smith {
3545c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3555c6c1daeSBarry Smith   PetscBool         iascii;
3565c6c1daeSBarry Smith 
3575c6c1daeSBarry Smith   PetscFunctionBegin;
3585c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
360a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3615c6c1daeSBarry Smith   PetscFunctionReturn(0);
3625c6c1daeSBarry Smith }
3635c6c1daeSBarry Smith 
3645c6c1daeSBarry Smith /*@C
3651575c14dSBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
3665c6c1daeSBarry Smith 
3675c6c1daeSBarry Smith     Collective on PetscViewer
3685c6c1daeSBarry Smith 
3695c6c1daeSBarry Smith     Input Parameters:
3701575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3715c6c1daeSBarry Smith 
3725c6c1daeSBarry Smith     Level: intermediate
3735c6c1daeSBarry Smith 
374e6abc3ddSVáclav Hapla     Notes:
375e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
3765c6c1daeSBarry Smith 
377db781477SPatrick Sanan .seealso: `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
378db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
379db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
3805c6c1daeSBarry Smith @*/
3811575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
3825c6c1daeSBarry Smith {
3835c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3845c6c1daeSBarry Smith   PetscBool         iascii;
3855c6c1daeSBarry Smith 
3865c6c1daeSBarry Smith   PetscFunctionBegin;
3875c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
38828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3899566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
3901575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3911575c14dSBarry Smith   PetscFunctionReturn(0);
3921575c14dSBarry Smith }
3931575c14dSBarry Smith 
3941575c14dSBarry Smith /*@C
3951575c14dSBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
3961575c14dSBarry Smith 
3971575c14dSBarry Smith     Collective on PetscViewer
3981575c14dSBarry Smith 
3991575c14dSBarry Smith     Input Parameters:
4001575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4011575c14dSBarry Smith 
4021575c14dSBarry Smith     Level: intermediate
4031575c14dSBarry Smith 
404e6abc3ddSVáclav Hapla     Notes:
405e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
4061575c14dSBarry Smith 
407db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerFlush()`,
408db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
409db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
4101575c14dSBarry Smith @*/
4111575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
4121575c14dSBarry Smith {
4131575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4141575c14dSBarry Smith   PetscBool         iascii;
4151575c14dSBarry Smith 
4161575c14dSBarry Smith   PetscFunctionBegin;
4171575c14dSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
41828b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
4199566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
4201575c14dSBarry Smith   if (iascii) {
4211575c14dSBarry Smith     ascii->allowsynchronized--;
42208401ef6SPierre Jolivet     PetscCheck(ascii->allowsynchronized >= 0,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
4231575c14dSBarry Smith   }
4245c6c1daeSBarry Smith   PetscFunctionReturn(0);
4255c6c1daeSBarry Smith }
4265c6c1daeSBarry Smith 
4271c297824SMatthew G. Knepley /*@C
4285c6c1daeSBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
4295c6c1daeSBarry Smith      lines are tabbed.
4305c6c1daeSBarry Smith 
4315c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4325c6c1daeSBarry Smith 
4335c6c1daeSBarry Smith     Input Parameters:
4341575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4355c6c1daeSBarry Smith 
4365c6c1daeSBarry Smith     Level: developer
4375c6c1daeSBarry Smith 
4385c6c1daeSBarry Smith     Fortran Note:
4395c6c1daeSBarry Smith     This routine is not supported in Fortran.
4405c6c1daeSBarry Smith 
441db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
442db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
443db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4445c6c1daeSBarry Smith @*/
4455c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
4465c6c1daeSBarry Smith {
4475c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4485c6c1daeSBarry Smith   PetscBool         iascii;
4495c6c1daeSBarry Smith 
4505c6c1daeSBarry Smith   PetscFunctionBegin;
4515c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
453a297a907SKarl Rupp   if (iascii) ascii->tab++;
4545c6c1daeSBarry Smith   PetscFunctionReturn(0);
4555c6c1daeSBarry Smith }
4565c6c1daeSBarry Smith 
4571c297824SMatthew G. Knepley /*@C
4585c6c1daeSBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
4595c6c1daeSBarry Smith      lines are tabbed.
4605c6c1daeSBarry Smith 
4615c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4625c6c1daeSBarry Smith 
4635c6c1daeSBarry Smith     Input Parameters:
4641575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4655c6c1daeSBarry Smith 
4665c6c1daeSBarry Smith     Level: developer
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith     Fortran Note:
4695c6c1daeSBarry Smith     This routine is not supported in Fortran.
4705c6c1daeSBarry Smith 
471db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
472db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
473db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
4745c6c1daeSBarry Smith @*/
4755c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
4765c6c1daeSBarry Smith {
4775c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4785c6c1daeSBarry Smith   PetscBool         iascii;
4795c6c1daeSBarry Smith 
4805c6c1daeSBarry Smith   PetscFunctionBegin;
4815c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4829566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
4835c6c1daeSBarry Smith   if (iascii) {
48408401ef6SPierre Jolivet     PetscCheck(ascii->tab > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
4855c6c1daeSBarry Smith     ascii->tab--;
4865c6c1daeSBarry Smith   }
4875c6c1daeSBarry Smith   PetscFunctionReturn(0);
4885c6c1daeSBarry Smith }
4895c6c1daeSBarry Smith 
4905c6c1daeSBarry Smith /*@
4915c6c1daeSBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
4925c6c1daeSBarry Smith 
4935c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith     Input Parameters:
4961575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
4975c6c1daeSBarry Smith -    flg - PETSC_TRUE or PETSC_FALSE
4985c6c1daeSBarry Smith 
4995c6c1daeSBarry Smith     Level: developer
5005c6c1daeSBarry Smith 
5015c6c1daeSBarry Smith     Fortran Note:
5025c6c1daeSBarry Smith     This routine is not supported in Fortran.
5035c6c1daeSBarry Smith 
504db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`,
505db781477SPatrick Sanan           `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`, `PetscViewerASCIIPushTab()`, `PetscViewerASCIIOpen()`,
506db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`
5075c6c1daeSBarry Smith @*/
5085c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
5095c6c1daeSBarry Smith {
5105c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5115c6c1daeSBarry Smith   PetscBool         iascii;
5125c6c1daeSBarry Smith 
5135c6c1daeSBarry Smith   PetscFunctionBegin;
5145c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
5159566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
5165c6c1daeSBarry Smith   if (iascii) {
517a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
518a297a907SKarl Rupp     else {
5195c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
5205c6c1daeSBarry Smith       ascii->tab       = 0;
5215c6c1daeSBarry Smith     }
5225c6c1daeSBarry Smith   }
5235c6c1daeSBarry Smith   PetscFunctionReturn(0);
5245c6c1daeSBarry Smith }
5255c6c1daeSBarry Smith 
5265c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5275c6c1daeSBarry Smith 
5285c6c1daeSBarry Smith /*@C
5295c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5305c6c1daeSBarry Smith     processor in the PetscViewer
5315c6c1daeSBarry Smith 
5325c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5335c6c1daeSBarry Smith 
5345c6c1daeSBarry Smith     Input Parameters:
5351575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5365c6c1daeSBarry Smith -    format - the usual printf() format string
5375c6c1daeSBarry Smith 
5385c6c1daeSBarry Smith     Level: developer
5395c6c1daeSBarry Smith 
5405c6c1daeSBarry Smith     Fortran Note:
5415c6c1daeSBarry Smith     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
5425c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5435c6c1daeSBarry Smith 
544db781477SPatrick Sanan .seealso: `PetscPrintf()`, `PetscSynchronizedPrintf()`, `PetscViewerASCIIOpen()`,
545db781477SPatrick Sanan           `PetscViewerASCIIPushTab()`, `PetscViewerASCIIPopTab()`, `PetscViewerASCIISynchronizedPrintf()`,
546db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`, `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPushSynchronized()`
5475c6c1daeSBarry Smith @*/
5485c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
5495c6c1daeSBarry Smith {
5505c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5515c6c1daeSBarry Smith   PetscMPIInt       rank;
552dd2fa690SBarry Smith   PetscInt          tab,intab = ascii->tab;
5535c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5543f08860eSBarry Smith   PetscBool         iascii;
5555c6c1daeSBarry Smith   int               err;
5565c6c1daeSBarry Smith 
5575c6c1daeSBarry Smith   PetscFunctionBegin;
5585c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
55928b400f6SJacob Faibussowitsch   PetscCheck(!ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5605c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
5619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
56228b400f6SJacob Faibussowitsch   PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
5639566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
564559f443fSBarry Smith   if (rank) PetscFunctionReturn(0);
5653f08860eSBarry Smith 
5663f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5673f08860eSBarry Smith     char        *string;
5683f08860eSBarry Smith     va_list     Argp;
5693f08860eSBarry Smith     size_t      fullLength;
5703f08860eSBarry Smith 
5719566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(QUEUESTRINGSIZE, &string));
5723f08860eSBarry Smith     va_start(Argp,format);
5739566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp));
5743f08860eSBarry Smith     va_end(Argp);
5759566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIISynchronizedPrintf(viewer,"%s",string));
5769566063dSJacob Faibussowitsch     PetscCall(PetscFree(string));
5773f08860eSBarry Smith   } else { /* write directly to file */
5785c6c1daeSBarry Smith     va_list Argp;
579559f443fSBarry Smith     /* flush my own messages that I may have queued up */
580559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
581559f443fSBarry Smith     PetscInt    i;
582559f443fSBarry Smith     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
5839566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string));
584559f443fSBarry Smith       previous = next;
585559f443fSBarry Smith       next     = next->next;
5869566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
5879566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
588559f443fSBarry Smith     }
58902c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
590559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
591dd2fa690SBarry Smith     tab = intab;
592a297a907SKarl Rupp     while (tab--) {
5939566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fd,"  "));
594a297a907SKarl Rupp     }
5955c6c1daeSBarry Smith 
5965c6c1daeSBarry Smith     va_start(Argp,format);
5979566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fd,format,Argp));
5985c6c1daeSBarry Smith     err  = fflush(fd);
59928b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6005c6c1daeSBarry Smith     if (petsc_history) {
6015c6c1daeSBarry Smith       va_start(Argp,format);
602dd2fa690SBarry Smith       tab = intab;
603a297a907SKarl Rupp       while (tab--) {
6049566063dSJacob Faibussowitsch         PetscCall(PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  "));
605a297a907SKarl Rupp       }
6069566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history,format,Argp));
6075c6c1daeSBarry Smith       err  = fflush(petsc_history);
60828b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6095c6c1daeSBarry Smith     }
6105c6c1daeSBarry Smith     va_end(Argp);
6115c6c1daeSBarry Smith   }
6125c6c1daeSBarry Smith   PetscFunctionReturn(0);
6135c6c1daeSBarry Smith }
6145c6c1daeSBarry Smith 
6155c6c1daeSBarry Smith /*@C
6165c6c1daeSBarry Smith      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
6175c6c1daeSBarry Smith 
6185c6c1daeSBarry Smith     Collective on PetscViewer
6195c6c1daeSBarry Smith 
6205c6c1daeSBarry Smith   Input Parameters:
6215c6c1daeSBarry Smith +  viewer - the PetscViewer; either ASCII or binary
6225c6c1daeSBarry Smith -  name - the name of the file it should use
6235c6c1daeSBarry Smith 
6245c6c1daeSBarry Smith     Level: advanced
6255c6c1daeSBarry Smith 
626db781477SPatrick Sanan .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerDestroy()`,
627db781477SPatrick Sanan           `PetscViewerASCIIGetPointer()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIISynchronizedPrintf()`
6285c6c1daeSBarry Smith 
6295c6c1daeSBarry Smith @*/
6305c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
6315c6c1daeSBarry Smith {
632cc843e7aSLisandro Dalcin   char           filename[PETSC_MAX_PATH_LEN];
6335c6c1daeSBarry Smith 
6345c6c1daeSBarry Smith   PetscFunctionBegin;
6355c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6365c6c1daeSBarry Smith   PetscValidCharPointer(name,2);
6379566063dSJacob Faibussowitsch   PetscCall(PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename)));
638cac4c232SBarry Smith   PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));
6395c6c1daeSBarry Smith   PetscFunctionReturn(0);
6405c6c1daeSBarry Smith }
6415c6c1daeSBarry Smith 
6425c6c1daeSBarry Smith /*@C
6435c6c1daeSBarry Smith      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
6445c6c1daeSBarry Smith 
6455c6c1daeSBarry Smith     Not Collective
6465c6c1daeSBarry Smith 
6475c6c1daeSBarry Smith   Input Parameter:
6485c6c1daeSBarry Smith .  viewer - the PetscViewer; either ASCII or binary
6495c6c1daeSBarry Smith 
6505c6c1daeSBarry Smith   Output Parameter:
6515c6c1daeSBarry Smith .  name - the name of the file it is using
6525c6c1daeSBarry Smith 
6535c6c1daeSBarry Smith     Level: advanced
6545c6c1daeSBarry Smith 
655db781477SPatrick Sanan .seealso: `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscViewerASCIIOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerFileSetName()`
6565c6c1daeSBarry Smith 
6575c6c1daeSBarry Smith @*/
6585c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
6595c6c1daeSBarry Smith {
6605c6c1daeSBarry Smith   PetscFunctionBegin;
6615c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6626e05b1faSLisandro Dalcin   PetscValidPointer(name,2);
663cac4c232SBarry Smith   PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));
6645c6c1daeSBarry Smith   PetscFunctionReturn(0);
6655c6c1daeSBarry Smith }
6665c6c1daeSBarry Smith 
6675c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
6685c6c1daeSBarry Smith {
6695c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6705c6c1daeSBarry Smith 
6715c6c1daeSBarry Smith   PetscFunctionBegin;
6725c6c1daeSBarry Smith   *name = vascii->filename;
6735c6c1daeSBarry Smith   PetscFunctionReturn(0);
6745c6c1daeSBarry Smith }
6755c6c1daeSBarry Smith 
6765c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
6775c6c1daeSBarry Smith {
6785c6c1daeSBarry Smith   size_t            len;
6795c6c1daeSBarry Smith   char              fname[PETSC_MAX_PATH_LEN],*gz;
6805c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6815c6c1daeSBarry Smith   PetscBool         isstderr,isstdout;
6825c6c1daeSBarry Smith   PetscMPIInt       rank;
6835c6c1daeSBarry Smith 
6845c6c1daeSBarry Smith   PetscFunctionBegin;
6859566063dSJacob Faibussowitsch   PetscCall(PetscViewerFileClose_ASCII(viewer));
6865c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
6879566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(name,&vascii->filename));
6885c6c1daeSBarry Smith 
6895c6c1daeSBarry Smith   /* Is this file to be compressed */
6905c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
691a297a907SKarl Rupp 
6929566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(vascii->filename,".gz",&gz));
6935c6c1daeSBarry Smith   if (gz) {
6949566063dSJacob Faibussowitsch     PetscCall(PetscStrlen(gz,&len));
6955c6c1daeSBarry Smith     if (len == 3) {
69608401ef6SPierre Jolivet       PetscCheck(vascii->mode == FILE_MODE_WRITE,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
6975c6c1daeSBarry Smith       *gz = 0;
6985c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
6995c6c1daeSBarry Smith     }
7005c6c1daeSBarry Smith   }
7019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
702dd400576SPatrick Sanan   if (rank == 0) {
7039566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name,"stderr",&isstderr));
7049566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(name,"stdout",&isstdout));
7055c6c1daeSBarry Smith     /* empty filename means stdout */
7065c6c1daeSBarry Smith     if (name[0] == 0)  isstdout = PETSC_TRUE;
7075c6c1daeSBarry Smith     if (isstderr)      vascii->fd = PETSC_STDERR;
7085c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
7095c6c1daeSBarry Smith     else {
7105c6c1daeSBarry Smith 
7119566063dSJacob Faibussowitsch       PetscCall(PetscFixFilename(name,fname));
7125c6c1daeSBarry Smith       switch (vascii->mode) {
7135c6c1daeSBarry Smith       case FILE_MODE_READ:
7145c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r");
7155c6c1daeSBarry Smith         break;
7165c6c1daeSBarry Smith       case FILE_MODE_WRITE:
7175c6c1daeSBarry Smith         vascii->fd = fopen(fname,"w");
7185c6c1daeSBarry Smith         break;
7195c6c1daeSBarry Smith       case FILE_MODE_APPEND:
7205c6c1daeSBarry Smith         vascii->fd = fopen(fname,"a");
7215c6c1daeSBarry Smith         break;
7225c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
7235c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
724a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
7255c6c1daeSBarry Smith         break;
7265c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
7275c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
7285c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
7295c6c1daeSBarry Smith         */
7305c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
731a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
732a297a907SKarl Rupp         else {
7339566063dSJacob Faibussowitsch           PetscCall(fseek(vascii->fd, 0, SEEK_END));
7345c6c1daeSBarry Smith         }
7355c6c1daeSBarry Smith         break;
7365c6c1daeSBarry Smith       default:
73798921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
7385c6c1daeSBarry Smith       }
73928b400f6SJacob Faibussowitsch       PetscCheck(vascii->fd,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
7405c6c1daeSBarry Smith     }
7415c6c1daeSBarry Smith   }
7425c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7435c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
7445c6c1daeSBarry Smith #endif
7455c6c1daeSBarry Smith   PetscFunctionReturn(0);
7465c6c1daeSBarry Smith }
7475c6c1daeSBarry Smith 
7483f08860eSBarry Smith PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
7495c6c1daeSBarry Smith {
7505c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
7515c6c1daeSBarry Smith 
7525c6c1daeSBarry Smith   PetscFunctionBegin;
7539566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
75428b400f6SJacob Faibussowitsch   PetscCheck(!vascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
755e5afcf28SBarry Smith   /*
7569530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7579530cbd7SBarry 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
7589530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7599530cbd7SBarry Smith 
7609530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7619530cbd7SBarry Smith      PCView_GASM().
762e5afcf28SBarry Smith   */
7639566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(viewer));
7649566063dSJacob Faibussowitsch   PetscCall(PetscViewerCreate(subcomm,outviewer));
7659566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetType(*outviewer,PETSCVIEWERASCII));
7669566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPushSynchronized(*outviewer));
7675c6c1daeSBarry Smith   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
7685c6c1daeSBarry Smith   ovascii->fd  = vascii->fd;
7695c6c1daeSBarry Smith   ovascii->tab = vascii->tab;
770ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7715c6c1daeSBarry Smith 
7725c6c1daeSBarry Smith   vascii->sviewer = *outviewer;
7735c6c1daeSBarry Smith   (*outviewer)->format  = viewer->format;
7745c6c1daeSBarry Smith   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
7753f08860eSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
7765c6c1daeSBarry Smith   PetscFunctionReturn(0);
7775c6c1daeSBarry Smith }
7785c6c1daeSBarry Smith 
7793f08860eSBarry Smith PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
7805c6c1daeSBarry Smith {
7815c6c1daeSBarry Smith   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
7825c6c1daeSBarry Smith 
7835c6c1daeSBarry Smith   PetscFunctionBegin;
78428b400f6SJacob Faibussowitsch   PetscCheck(ascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
78508401ef6SPierre Jolivet   PetscCheck(ascii->sviewer == *outviewer,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
7865c6c1daeSBarry Smith 
7879566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(*outviewer));
788e5afcf28SBarry Smith   ascii->sviewer             = NULL;
7895c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
7909566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(outviewer));
7919566063dSJacob Faibussowitsch   PetscCall(PetscViewerASCIIPopSynchronized(viewer));
7925c6c1daeSBarry Smith   PetscFunctionReturn(0);
7935c6c1daeSBarry Smith }
7945c6c1daeSBarry Smith 
7952bf49c77SBarry Smith PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
7962bf49c77SBarry Smith {
7972bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
7982bf49c77SBarry Smith 
7992bf49c77SBarry Smith   PetscFunctionBegin;
8002bf49c77SBarry Smith   if (ascii->filename) {
8019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename));
8022bf49c77SBarry Smith   }
8032bf49c77SBarry Smith   PetscFunctionReturn(0);
8042bf49c77SBarry Smith }
8052bf49c77SBarry Smith 
8068556b5ebSBarry Smith /*MC
8078556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
8088556b5ebSBarry Smith 
809c2e3fba1SPatrick Sanan .seealso: `PETSC_VIEWER_STDOUT_()`, `PETSC_VIEWER_STDOUT_SELF`, `PETSC_VIEWER_STDOUT_WORLD`, `PetscViewerCreate()`, `PetscViewerASCIIOpen()`,
810db781477SPatrick Sanan           `PetscViewerMatlabOpen()`, `VecView()`, `DMView()`, `PetscViewerMatlabPutArray()`, `PETSCVIEWERBINARY`, `PETSCVIEWERMATLAB`,
811db781477SPatrick Sanan           `PetscViewerFileSetName()`, `PetscViewerFileSetMode()`, `PetscViewerFormat`, `PetscViewerType`, `PetscViewerSetType()`
8128556b5ebSBarry Smith 
8131b266c99SBarry Smith   Level: beginner
8141b266c99SBarry Smith 
8158556b5ebSBarry Smith M*/
8168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
8175c6c1daeSBarry Smith {
8185c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
8195c6c1daeSBarry Smith 
8205c6c1daeSBarry Smith   PetscFunctionBegin;
8219566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(viewer,&vascii));
8225c6c1daeSBarry Smith   viewer->data = (void*)vascii;
8235c6c1daeSBarry Smith 
8245c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
8255c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
826559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
827559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
8282bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
8291d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
8305c6c1daeSBarry Smith 
8315c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
8325c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
8335c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
83402c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
83502c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
83602c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
8375c6c1daeSBarry Smith   vascii->tab       = 0;
8385c6c1daeSBarry Smith   vascii->tab_store = 0;
83902c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
8405c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8415c6c1daeSBarry Smith 
8429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII));
8439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII));
8449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII));
8459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII));
8465c6c1daeSBarry Smith   PetscFunctionReturn(0);
8475c6c1daeSBarry Smith }
8485c6c1daeSBarry Smith 
8495c6c1daeSBarry Smith /*@C
8505c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8515c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8525c6c1daeSBarry Smith     second, etc.
8535c6c1daeSBarry Smith 
8545c6c1daeSBarry Smith     Not Collective, must call collective PetscViewerFlush() to get the results out
8555c6c1daeSBarry Smith 
8565c6c1daeSBarry Smith     Input Parameters:
8575c6c1daeSBarry Smith +   viewer - the ASCII PetscViewer
8585c6c1daeSBarry Smith -   format - the usual printf() format string
8595c6c1daeSBarry Smith 
8605c6c1daeSBarry Smith     Level: intermediate
8615c6c1daeSBarry Smith 
86295452b02SPatrick Sanan     Notes:
863e6abc3ddSVáclav Hapla     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
864e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
865e6abc3ddSVáclav Hapla     The actual synchronized print is then done using PetscViewerFlush().
866e6abc3ddSVáclav Hapla     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
867e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
868e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
869e6abc3ddSVáclav Hapla $ PetscViewerASCIIPushSynchronized(viewer);
870e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
871e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
872e6abc3ddSVáclav Hapla $ ...
873e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
874e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
875e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
876e6abc3ddSVáclav Hapla $ ...
877e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
878e6abc3ddSVáclav Hapla $ PetscViewerASCIIPopSynchronized(viewer);
8795c6c1daeSBarry Smith 
8805c6c1daeSBarry Smith     Fortran Note:
8815c6c1daeSBarry Smith       Can only print a single character* string
8825c6c1daeSBarry Smith 
883db781477SPatrick Sanan .seealso: `PetscViewerASCIIPushSynchronized()`, `PetscViewerFlush()`, `PetscViewerASCIIPopSynchronized()`,
884db781477SPatrick Sanan           `PetscSynchronizedPrintf()`, `PetscViewerASCIIPrintf()`, `PetscViewerASCIIOpen()`,
885db781477SPatrick Sanan           `PetscViewerCreate()`, `PetscViewerDestroy()`, `PetscViewerSetType()`
8865c6c1daeSBarry Smith @*/
8875c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
8885c6c1daeSBarry Smith {
8895c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
8903f08860eSBarry Smith   PetscMPIInt       rank;
8915c6c1daeSBarry Smith   PetscInt          tab = vascii->tab;
8925c6c1daeSBarry Smith   MPI_Comm          comm;
8935c6c1daeSBarry Smith   FILE              *fp;
894559f443fSBarry Smith   PetscBool         iascii,hasbviewer = PETSC_FALSE;
8955c6c1daeSBarry Smith   int               err;
8965c6c1daeSBarry Smith 
8975c6c1daeSBarry Smith   PetscFunctionBegin;
8985c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
8995c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
9009566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
90128b400f6SJacob Faibussowitsch   PetscCheck(iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
90228b400f6SJacob Faibussowitsch   PetscCheck(vascii->allowsynchronized,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
9035c6c1daeSBarry Smith 
9049566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
9059566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(comm,&rank));
9065c6c1daeSBarry Smith 
907559f443fSBarry Smith   if (vascii->bviewer) {
908559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
909dd400576SPatrick Sanan     if (rank == 0) {
910559f443fSBarry Smith       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
9119566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)viewer,&comm));
9129566063dSJacob Faibussowitsch       PetscCallMPI(MPI_Comm_rank(comm,&rank));
913559f443fSBarry Smith     }
914559f443fSBarry Smith   }
9153f08860eSBarry Smith 
916559f443fSBarry Smith   fp   = vascii->fd;
917559f443fSBarry Smith 
918dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
9195c6c1daeSBarry Smith     va_list Argp;
920559f443fSBarry Smith     /* flush my own messages that I may have queued up */
921559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
922559f443fSBarry Smith     PetscInt    i;
923559f443fSBarry Smith     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
9249566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm,fp,"%s",next->string));
925559f443fSBarry Smith       previous = next;
926559f443fSBarry Smith       next     = next->next;
9279566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous->string));
9289566063dSJacob Faibussowitsch       PetscCall(PetscFree(previous));
929559f443fSBarry Smith     }
93002c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
931559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
9325c6c1daeSBarry Smith 
933a297a907SKarl Rupp     while (tab--) {
9349566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(PETSC_COMM_SELF,fp,"  "));
935a297a907SKarl Rupp     }
9365c6c1daeSBarry Smith 
9375c6c1daeSBarry Smith     va_start(Argp,format);
9389566063dSJacob Faibussowitsch     PetscCall((*PetscVFPrintf)(fp,format,Argp));
9395c6c1daeSBarry Smith     err  = fflush(fp);
94028b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9415c6c1daeSBarry Smith     if (petsc_history) {
9425c6c1daeSBarry Smith       va_start(Argp,format);
9439566063dSJacob Faibussowitsch       PetscCall((*PetscVFPrintf)(petsc_history,format,Argp));
9445c6c1daeSBarry Smith       err  = fflush(petsc_history);
94528b400f6SJacob Faibussowitsch       PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9465c6c1daeSBarry Smith     }
9475c6c1daeSBarry Smith     va_end(Argp);
948559f443fSBarry Smith   } else { /* other processors add to queue */
9495c6c1daeSBarry Smith     char        *string;
9505c6c1daeSBarry Smith     va_list     Argp;
9515c6c1daeSBarry Smith     size_t      fullLength;
9525c6c1daeSBarry Smith     PrintfQueue next;
9535c6c1daeSBarry Smith 
9549566063dSJacob Faibussowitsch     PetscCall(PetscNew(&next));
955559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
956559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
957559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
958a297a907SKarl Rupp     } else {
959559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
960a297a907SKarl Rupp     }
961559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9625c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
9639566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(next->size, &next->string));
9645c6c1daeSBarry Smith     string     = next->string;
9655c6c1daeSBarry Smith     tab       *= 2;
966a297a907SKarl Rupp     while (tab--) {
967a297a907SKarl Rupp       *string++ = ' ';
968a297a907SKarl Rupp     }
9695c6c1daeSBarry Smith     va_start(Argp,format);
9709566063dSJacob Faibussowitsch     PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp));
9715c6c1daeSBarry Smith     va_end(Argp);
972cb500232SBarry Smith     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
9739566063dSJacob Faibussowitsch       PetscCall(PetscFree(next->string));
97414416c0eSBarry Smith       next->size = fullLength + 2*vascii->tab;
9759566063dSJacob Faibussowitsch       PetscCall(PetscCalloc1(next->size, &next->string));
97614416c0eSBarry Smith       string     = next->string;
97714416c0eSBarry Smith       tab        = 2*vascii->tab;
97814416c0eSBarry Smith       while (tab--) {
97914416c0eSBarry Smith         *string++ = ' ';
98014416c0eSBarry Smith       }
98114416c0eSBarry Smith       va_start(Argp,format);
9829566063dSJacob Faibussowitsch       PetscCall(PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp));
98314416c0eSBarry Smith       va_end(Argp);
98414416c0eSBarry Smith     }
9855c6c1daeSBarry Smith   }
9865c6c1daeSBarry Smith   PetscFunctionReturn(0);
9875c6c1daeSBarry Smith }
9885c6c1daeSBarry Smith 
9892655f987SMichael Lange /*@C
990f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
9912655f987SMichael Lange 
992f8859db6SBarry Smith    Only process 0 in the PetscViewer may call this
9932655f987SMichael Lange 
9942655f987SMichael Lange    Input Parameters:
9952655f987SMichael Lange +  viewer - the ascii viewer
9962655f987SMichael Lange .  data - location to write the data
997060da220SMatthew G. Knepley .  num - number of items of data to read
9982655f987SMichael Lange -  datatype - type of data to read
9992655f987SMichael Lange 
1000f8e4bde8SMatthew G. Knepley    Output Parameters:
1001060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
1002f8e4bde8SMatthew G. Knepley 
10032655f987SMichael Lange    Level: beginner
10042655f987SMichael Lange 
1005db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetName()`
1006db781477SPatrick Sanan           `VecView()`, `MatView()`, `VecLoad()`, `MatLoad()`, `PetscViewerBinaryGetDescriptor()`,
1007db781477SPatrick Sanan           `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`, `PetscViewer`, `PetscViewerBinaryRead()`
10082655f987SMichael Lange @*/
1009060da220SMatthew G. Knepley PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
10102655f987SMichael Lange {
10112655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
10122655f987SMichael Lange   FILE              *fd = vascii->fd;
10132655f987SMichael Lange   PetscInt           i;
10143b7fe8c3SMatthew G. Knepley   int                ret = 0;
1015f8859db6SBarry Smith   PetscMPIInt        rank;
10162655f987SMichael Lange 
10172655f987SMichael Lange   PetscFunctionBegin;
10182655f987SMichael Lange   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
10199566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank));
1020c5853193SPierre Jolivet   PetscCheck(rank == 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1021060da220SMatthew G. Knepley   for (i=0; i<num; i++) {
1022f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1023f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1024a05e1a72SSatish Balay     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1025f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
10269e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1027972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1028f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1029f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1030a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
1031fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
1032fba955ccSBarry Smith       double tmp;
1033fba955ccSBarry Smith       ret = fscanf(fd, "%lg", &tmp);
1034a6e181c6SToby Isaac       ((__float128*)data)[i] = tmp;
1035a6e181c6SToby Isaac     }
1036fba955ccSBarry Smith #endif
103798921bdaSJacob Faibussowitsch     else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
103828b400f6SJacob Faibussowitsch     PetscCheck(ret,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1039f8e4bde8SMatthew G. Knepley     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10402655f987SMichael Lange   }
1041060da220SMatthew G. Knepley   if (count) *count = i;
104208401ef6SPierre Jolivet   else PetscCheck(ret >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
10432655f987SMichael Lange   PetscFunctionReturn(0);
10442655f987SMichael Lange }
1045