xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 580bdb303e1ee3b1222b2042810b4c26340259c6)
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   PetscErrorCode    ierr;
95c6c1daeSBarry Smith   PetscMPIInt       rank;
105c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
115c6c1daeSBarry Smith   int               err;
125c6c1daeSBarry Smith 
135c6c1daeSBarry Smith   PetscFunctionBegin;
14e5afcf28SBarry Smith   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
15ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
165c6c1daeSBarry Smith   if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
175c6c1daeSBarry Smith     if (vascii->fd && vascii->closefile) {
185c6c1daeSBarry Smith       err = fclose(vascii->fd);
195c6c1daeSBarry Smith       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
205c6c1daeSBarry Smith     }
215c6c1daeSBarry Smith     if (vascii->storecompressed) {
225c6c1daeSBarry Smith       char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
235c6c1daeSBarry Smith       FILE *fp;
24a126751eSBarry Smith       ierr = PetscStrncpy(par,"gzip ",sizeof(par));CHKERRQ(ierr);
25a126751eSBarry Smith       ierr = PetscStrlcat(par,vascii->filename,sizeof(par));CHKERRQ(ierr);
265c6c1daeSBarry Smith #if defined(PETSC_HAVE_POPEN)
270298fd71SBarry Smith       ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr);
28f23aa3ddSBarry Smith       if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
29016831caSBarry Smith       ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr);
305c6c1daeSBarry Smith #else
315c6c1daeSBarry Smith       SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
325c6c1daeSBarry Smith #endif
335c6c1daeSBarry Smith     }
345c6c1daeSBarry Smith   }
355c6c1daeSBarry Smith   ierr = PetscFree(vascii->filename);CHKERRQ(ierr);
365c6c1daeSBarry Smith   PetscFunctionReturn(0);
375c6c1daeSBarry Smith }
385c6c1daeSBarry Smith 
395c6c1daeSBarry Smith /* ----------------------------------------------------------------------*/
405c6c1daeSBarry Smith PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
415c6c1daeSBarry Smith {
425c6c1daeSBarry Smith   PetscErrorCode    ierr;
435c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
445c6c1daeSBarry Smith   PetscViewerLink   *vlink;
455c6c1daeSBarry Smith   PetscBool         flg;
465c6c1daeSBarry Smith 
475c6c1daeSBarry Smith   PetscFunctionBegin;
48e5afcf28SBarry Smith   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
495c6c1daeSBarry Smith   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
505c6c1daeSBarry Smith   ierr = PetscFree(vascii);CHKERRQ(ierr);
515c6c1daeSBarry Smith 
525c6c1daeSBarry Smith   /* remove the viewer from the list in the MPI Communicator */
535c6c1daeSBarry Smith   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
5412801b39SBarry Smith     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
555c6c1daeSBarry Smith   }
565c6c1daeSBarry Smith 
5747435625SJed Brown   ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
585c6c1daeSBarry Smith   if (flg) {
595c6c1daeSBarry Smith     if (vlink && vlink->viewer == viewer) {
60e5840a18SBarry Smith       if (vlink->next) {
6147435625SJed Brown         ierr = MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr);
62e5840a18SBarry Smith       } else {
6347435625SJed Brown         ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);CHKERRQ(ierr);
64e5840a18SBarry Smith       }
655c6c1daeSBarry Smith       ierr = PetscFree(vlink);CHKERRQ(ierr);
665c6c1daeSBarry Smith     } else {
675c6c1daeSBarry Smith       while (vlink && vlink->next) {
685c6c1daeSBarry Smith         if (vlink->next->viewer == viewer) {
695c6c1daeSBarry Smith           PetscViewerLink *nv = vlink->next;
705c6c1daeSBarry Smith           vlink->next = vlink->next->next;
715c6c1daeSBarry Smith           ierr = PetscFree(nv);CHKERRQ(ierr);
725c6c1daeSBarry Smith         }
735c6c1daeSBarry Smith         vlink = vlink->next;
745c6c1daeSBarry Smith       }
755c6c1daeSBarry Smith     }
765c6c1daeSBarry Smith   }
77aa139df6SJed Brown 
78aa139df6SJed Brown   if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
79aa139df6SJed Brown     PetscViewer aviewer;
8047435625SJed Brown     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
81aa139df6SJed Brown     if (flg && aviewer == viewer) {
8247435625SJed Brown       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);CHKERRQ(ierr);
83aa139df6SJed Brown     }
84aa139df6SJed Brown   }
85aa139df6SJed Brown   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
86aa139df6SJed Brown     PetscViewer aviewer;
8747435625SJed Brown     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
88aa139df6SJed Brown     if (flg && aviewer == viewer) {
8947435625SJed Brown       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);CHKERRQ(ierr);
90aa139df6SJed Brown     }
91aa139df6SJed Brown   }
925c6c1daeSBarry Smith   PetscFunctionReturn(0);
935c6c1daeSBarry Smith }
945c6c1daeSBarry Smith 
953f08860eSBarry Smith PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
965c6c1daeSBarry Smith {
975c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
985c6c1daeSBarry Smith   PetscErrorCode    ierr;
995fd66863SKarl Rupp 
1005c6c1daeSBarry Smith   PetscFunctionBegin;
1013f08860eSBarry Smith   ierr = PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);CHKERRQ(ierr);
1025c6c1daeSBarry Smith   PetscFunctionReturn(0);
1035c6c1daeSBarry Smith }
1045c6c1daeSBarry Smith 
1055c6c1daeSBarry Smith PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
1065c6c1daeSBarry Smith {
1075c6c1daeSBarry Smith   PetscErrorCode    ierr;
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;
115e5afcf28SBarry Smith   if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
116559f443fSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
117559f443fSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
118559f443fSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
119559f443fSBarry Smith 
120559f443fSBarry Smith   if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
1215c6c1daeSBarry Smith     err = fflush(vascii->fd);
1225c6c1daeSBarry Smith     if (err) SETERRQ(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 
130559f443fSBarry Smith     ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
131559f443fSBarry Smith 
132559f443fSBarry Smith     /* First processor waits for messages from all other processors */
133559f443fSBarry Smith     if (!rank) {
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) {
138559f443fSBarry Smith           ierr = PetscFPrintf(comm,fd,"%s",next->string);CHKERRQ(ierr);
139559f443fSBarry Smith         } else {
140559f443fSBarry Smith           ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);CHKERRQ(ierr);
141559f443fSBarry Smith         }
142559f443fSBarry Smith         previous = next;
143559f443fSBarry Smith         next     = next->next;
144559f443fSBarry Smith         ierr     = PetscFree(previous->string);CHKERRQ(ierr);
145559f443fSBarry Smith         ierr     = PetscFree(previous);CHKERRQ(ierr);
146559f443fSBarry Smith       }
147559f443fSBarry Smith       vascii->petsc_printfqueue       = 0;
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 */
151559f443fSBarry Smith         ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
152559f443fSBarry Smith         ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
153559f443fSBarry Smith         for (j=0; j<n; j++) {
154559f443fSBarry Smith           PetscMPIInt size = 0;
155559f443fSBarry Smith 
156559f443fSBarry Smith           ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
157559f443fSBarry Smith           ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
158559f443fSBarry Smith           ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
159559f443fSBarry Smith           if (!vascii->bviewer) {
160559f443fSBarry Smith             ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
161559f443fSBarry Smith           } else {
162559f443fSBarry Smith             ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);CHKERRQ(ierr);
163559f443fSBarry Smith           }
164559f443fSBarry Smith           ierr = PetscFree(message);CHKERRQ(ierr);
165559f443fSBarry Smith         }
166559f443fSBarry Smith       }
167559f443fSBarry Smith     } else { /* other processors send queue to processor 0 */
168559f443fSBarry Smith       PrintfQueue next = vascii->petsc_printfqueuebase,previous;
169559f443fSBarry Smith 
170559f443fSBarry Smith       ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
171559f443fSBarry Smith       ierr = MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
172559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
173559f443fSBarry Smith         ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
174559f443fSBarry Smith         ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
175559f443fSBarry Smith         previous = next;
176559f443fSBarry Smith         next     = next->next;
177559f443fSBarry Smith         ierr     = PetscFree(previous->string);CHKERRQ(ierr);
178559f443fSBarry Smith         ierr     = PetscFree(previous);CHKERRQ(ierr);
179559f443fSBarry Smith       }
180559f443fSBarry Smith       vascii->petsc_printfqueue       = 0;
181559f443fSBarry Smith       vascii->petsc_printfqueuelength = 0;
182559f443fSBarry Smith     }
183559f443fSBarry Smith     ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
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 
2065c6c1daeSBarry Smith 
2075c6c1daeSBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
2085c6c1daeSBarry Smith           PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
2095c6c1daeSBarry Smith @*/
2105c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
2115c6c1daeSBarry Smith {
2125c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2135c6c1daeSBarry Smith 
2145c6c1daeSBarry Smith   PetscFunctionBegin;
2155c6c1daeSBarry Smith   *fd = vascii->fd;
2165c6c1daeSBarry Smith   PetscFunctionReturn(0);
2175c6c1daeSBarry Smith }
2185c6c1daeSBarry Smith 
2195c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
2205c6c1daeSBarry Smith {
2215c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2225c6c1daeSBarry Smith 
2235c6c1daeSBarry Smith   PetscFunctionBegin;
2245c6c1daeSBarry Smith   *mode = vascii->mode;
2255c6c1daeSBarry Smith   PetscFunctionReturn(0);
2265c6c1daeSBarry Smith }
2275c6c1daeSBarry Smith 
2285c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
2295c6c1daeSBarry Smith {
2305c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
2315c6c1daeSBarry Smith 
2325c6c1daeSBarry Smith   PetscFunctionBegin;
2335c6c1daeSBarry Smith   vascii->mode = mode;
2345c6c1daeSBarry Smith   PetscFunctionReturn(0);
2355c6c1daeSBarry Smith }
2365c6c1daeSBarry Smith 
2375c6c1daeSBarry Smith /*
2385c6c1daeSBarry Smith    If petsc_history is on, then all Petsc*Printf() results are saved
2395c6c1daeSBarry Smith    if the appropriate (usually .petschistory) file.
2405c6c1daeSBarry Smith */
24195c0884eSLisandro Dalcin PETSC_INTERN FILE *petsc_history;
2425c6c1daeSBarry Smith 
2435c6c1daeSBarry Smith /*@
2445c6c1daeSBarry Smith     PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
2475c6c1daeSBarry Smith 
2485c6c1daeSBarry Smith     Input Parameters:
2491575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
2505c6c1daeSBarry Smith -    tabs - number of tabs
2515c6c1daeSBarry Smith 
2525c6c1daeSBarry Smith     Level: developer
2535c6c1daeSBarry Smith 
2545c6c1daeSBarry Smith     Fortran Note:
2555c6c1daeSBarry Smith     This routine is not supported in Fortran.
2565c6c1daeSBarry Smith 
2575c6c1daeSBarry Smith 
2585c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
2595c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2605c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
2615c6c1daeSBarry Smith @*/
2625c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
2635c6c1daeSBarry Smith {
2645c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2655c6c1daeSBarry Smith   PetscBool         iascii;
2665c6c1daeSBarry Smith   PetscErrorCode    ierr;
2675c6c1daeSBarry Smith 
2685c6c1daeSBarry Smith   PetscFunctionBegin;
2695c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2705c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
271a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2725c6c1daeSBarry Smith   PetscFunctionReturn(0);
2735c6c1daeSBarry Smith }
2745c6c1daeSBarry Smith 
2755c6c1daeSBarry Smith /*@
2765c6c1daeSBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
2775c6c1daeSBarry Smith 
2785c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2795c6c1daeSBarry Smith 
2805c6c1daeSBarry Smith     Input Parameters:
2811575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
2825c6c1daeSBarry Smith     Output Parameters:
2835c6c1daeSBarry Smith .    tabs - number of tabs
2845c6c1daeSBarry Smith 
2855c6c1daeSBarry Smith     Level: developer
2865c6c1daeSBarry Smith 
2875c6c1daeSBarry Smith     Fortran Note:
2885c6c1daeSBarry Smith     This routine is not supported in Fortran.
2895c6c1daeSBarry Smith 
2905c6c1daeSBarry Smith 
2915c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
2925c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2935c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
2945c6c1daeSBarry Smith @*/
2955c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
2965c6c1daeSBarry Smith {
2975c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2985c6c1daeSBarry Smith   PetscBool         iascii;
2995c6c1daeSBarry Smith   PetscErrorCode    ierr;
3005c6c1daeSBarry Smith 
3015c6c1daeSBarry Smith   PetscFunctionBegin;
3025c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3035c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
304a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
3055c6c1daeSBarry Smith   PetscFunctionReturn(0);
3065c6c1daeSBarry Smith }
3075c6c1daeSBarry Smith 
3085c6c1daeSBarry Smith /*@
3095c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
3105c6c1daeSBarry Smith 
3115c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3125c6c1daeSBarry Smith 
3135c6c1daeSBarry Smith     Input Parameters:
3141575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3155c6c1daeSBarry Smith -    tabs - number of tabs
3165c6c1daeSBarry Smith 
3175c6c1daeSBarry Smith     Level: developer
3185c6c1daeSBarry Smith 
3195c6c1daeSBarry Smith     Fortran Note:
3205c6c1daeSBarry Smith     This routine is not supported in Fortran.
3215c6c1daeSBarry Smith 
3225c6c1daeSBarry Smith 
3235c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3245c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3255c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3265c6c1daeSBarry Smith @*/
3275c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
3285c6c1daeSBarry Smith {
3295c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3305c6c1daeSBarry Smith   PetscBool         iascii;
3315c6c1daeSBarry Smith   PetscErrorCode    ierr;
3325c6c1daeSBarry Smith 
3335c6c1daeSBarry Smith   PetscFunctionBegin;
3345c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3355c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
336a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3375c6c1daeSBarry Smith   PetscFunctionReturn(0);
3385c6c1daeSBarry Smith }
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith /*@
3415c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3425c6c1daeSBarry Smith 
3435c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3445c6c1daeSBarry Smith 
3455c6c1daeSBarry Smith     Input Parameters:
3461575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3475c6c1daeSBarry Smith -    tabs - number of tabs
3485c6c1daeSBarry Smith 
3495c6c1daeSBarry Smith     Level: developer
3505c6c1daeSBarry Smith 
3515c6c1daeSBarry Smith     Fortran Note:
3525c6c1daeSBarry Smith     This routine is not supported in Fortran.
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith 
3555c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3565c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3575c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3585c6c1daeSBarry Smith @*/
3595c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
3605c6c1daeSBarry Smith {
3615c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3625c6c1daeSBarry Smith   PetscBool         iascii;
3635c6c1daeSBarry Smith   PetscErrorCode    ierr;
3645c6c1daeSBarry Smith 
3655c6c1daeSBarry Smith   PetscFunctionBegin;
3665c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3675c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
368a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3695c6c1daeSBarry Smith   PetscFunctionReturn(0);
3705c6c1daeSBarry Smith }
3715c6c1daeSBarry Smith 
3725c6c1daeSBarry Smith /*@C
3731575c14dSBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
3745c6c1daeSBarry Smith 
3755c6c1daeSBarry Smith     Collective on PetscViewer
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith     Input Parameters:
3781575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3795c6c1daeSBarry Smith 
3805c6c1daeSBarry Smith     Level: intermediate
3815c6c1daeSBarry Smith 
3825c6c1daeSBarry Smith 
3831575c14dSBarry Smith .seealso: PetscViewerASCIIPopSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3845c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3855c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
3865c6c1daeSBarry Smith @*/
3871575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
3885c6c1daeSBarry Smith {
3895c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3905c6c1daeSBarry Smith   PetscBool         iascii;
3915c6c1daeSBarry Smith   PetscErrorCode    ierr;
3925c6c1daeSBarry Smith 
3935c6c1daeSBarry Smith   PetscFunctionBegin;
3945c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
395e5afcf28SBarry Smith   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3965c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3971575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3981575c14dSBarry Smith   PetscFunctionReturn(0);
3991575c14dSBarry Smith }
4001575c14dSBarry Smith 
4011575c14dSBarry Smith /*@C
4021575c14dSBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
4031575c14dSBarry Smith 
4041575c14dSBarry Smith     Collective on PetscViewer
4051575c14dSBarry Smith 
4061575c14dSBarry Smith     Input Parameters:
4071575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4081575c14dSBarry Smith 
4091575c14dSBarry Smith     Level: intermediate
4101575c14dSBarry Smith 
4111575c14dSBarry Smith 
4121575c14dSBarry Smith .seealso: PetscViewerASCIIPushSynchronized(), PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4131575c14dSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4141575c14dSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4151575c14dSBarry Smith @*/
4161575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPopSynchronized(PetscViewer viewer)
4171575c14dSBarry Smith {
4181575c14dSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4191575c14dSBarry Smith   PetscBool         iascii;
4201575c14dSBarry Smith   PetscErrorCode    ierr;
4211575c14dSBarry Smith 
4221575c14dSBarry Smith   PetscFunctionBegin;
4231575c14dSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
424e5afcf28SBarry Smith   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
4251575c14dSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
4261575c14dSBarry Smith   if (iascii) {
4271575c14dSBarry Smith     ascii->allowsynchronized--;
4281575c14dSBarry Smith     if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
4291575c14dSBarry Smith   }
4305c6c1daeSBarry Smith   PetscFunctionReturn(0);
4315c6c1daeSBarry Smith }
4325c6c1daeSBarry Smith 
4331c297824SMatthew G. Knepley /*@C
4345c6c1daeSBarry Smith     PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
4355c6c1daeSBarry Smith      lines are tabbed.
4365c6c1daeSBarry Smith 
4375c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4385c6c1daeSBarry Smith 
4395c6c1daeSBarry Smith     Input Parameters:
4401575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4415c6c1daeSBarry Smith 
4425c6c1daeSBarry Smith     Level: developer
4435c6c1daeSBarry Smith 
4445c6c1daeSBarry Smith     Fortran Note:
4455c6c1daeSBarry Smith     This routine is not supported in Fortran.
4465c6c1daeSBarry Smith 
4475c6c1daeSBarry Smith 
4485c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4495c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4505c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4515c6c1daeSBarry Smith @*/
4525c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
4535c6c1daeSBarry Smith {
4545c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4555c6c1daeSBarry Smith   PetscBool         iascii;
4565c6c1daeSBarry Smith   PetscErrorCode    ierr;
4575c6c1daeSBarry Smith 
4585c6c1daeSBarry Smith   PetscFunctionBegin;
4595c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4605c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
461a297a907SKarl Rupp   if (iascii) ascii->tab++;
4625c6c1daeSBarry Smith   PetscFunctionReturn(0);
4635c6c1daeSBarry Smith }
4645c6c1daeSBarry Smith 
4651c297824SMatthew G. Knepley /*@C
4665c6c1daeSBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
4675c6c1daeSBarry Smith      lines are tabbed.
4685c6c1daeSBarry Smith 
4695c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4705c6c1daeSBarry Smith 
4715c6c1daeSBarry Smith     Input Parameters:
4721575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4735c6c1daeSBarry Smith 
4745c6c1daeSBarry Smith     Level: developer
4755c6c1daeSBarry Smith 
4765c6c1daeSBarry Smith     Fortran Note:
4775c6c1daeSBarry Smith     This routine is not supported in Fortran.
4785c6c1daeSBarry Smith 
4795c6c1daeSBarry Smith 
4805c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4815c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4825c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4835c6c1daeSBarry Smith @*/
4845c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
4855c6c1daeSBarry Smith {
4865c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4875c6c1daeSBarry Smith   PetscErrorCode    ierr;
4885c6c1daeSBarry Smith   PetscBool         iascii;
4895c6c1daeSBarry Smith 
4905c6c1daeSBarry Smith   PetscFunctionBegin;
4915c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4925c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
4935c6c1daeSBarry Smith   if (iascii) {
4945c6c1daeSBarry Smith     if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
4955c6c1daeSBarry Smith     ascii->tab--;
4965c6c1daeSBarry Smith   }
4975c6c1daeSBarry Smith   PetscFunctionReturn(0);
4985c6c1daeSBarry Smith }
4995c6c1daeSBarry Smith 
5005c6c1daeSBarry Smith /*@
5015c6c1daeSBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
5025c6c1daeSBarry Smith 
5035c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5045c6c1daeSBarry Smith 
5055c6c1daeSBarry Smith     Input Parameters:
5061575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5075c6c1daeSBarry Smith -    flg - PETSC_TRUE or PETSC_FALSE
5085c6c1daeSBarry Smith 
5095c6c1daeSBarry Smith     Level: developer
5105c6c1daeSBarry Smith 
5115c6c1daeSBarry Smith     Fortran Note:
5125c6c1daeSBarry Smith     This routine is not supported in Fortran.
5135c6c1daeSBarry Smith 
5145c6c1daeSBarry Smith 
5155c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
5165c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
5175c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
5185c6c1daeSBarry Smith @*/
5195c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
5205c6c1daeSBarry Smith {
5215c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5225c6c1daeSBarry Smith   PetscBool         iascii;
5235c6c1daeSBarry Smith   PetscErrorCode    ierr;
5245c6c1daeSBarry Smith 
5255c6c1daeSBarry Smith   PetscFunctionBegin;
5265c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
5275c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
5285c6c1daeSBarry Smith   if (iascii) {
529a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
530a297a907SKarl Rupp     else {
5315c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
5325c6c1daeSBarry Smith       ascii->tab       = 0;
5335c6c1daeSBarry Smith     }
5345c6c1daeSBarry Smith   }
5355c6c1daeSBarry Smith   PetscFunctionReturn(0);
5365c6c1daeSBarry Smith }
5375c6c1daeSBarry Smith 
5385c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5395c6c1daeSBarry Smith 
5405c6c1daeSBarry Smith 
5415c6c1daeSBarry Smith /*@C
5425c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5435c6c1daeSBarry Smith     processor in the PetscViewer
5445c6c1daeSBarry Smith 
5455c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5465c6c1daeSBarry Smith 
5475c6c1daeSBarry Smith     Input Parameters:
5481575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5495c6c1daeSBarry Smith -    format - the usual printf() format string
5505c6c1daeSBarry Smith 
5515c6c1daeSBarry Smith     Level: developer
5525c6c1daeSBarry Smith 
5535c6c1daeSBarry Smith     Fortran Note:
5545c6c1daeSBarry Smith     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
5555c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5565c6c1daeSBarry Smith 
5575c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
5585c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
5591575c14dSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
5605c6c1daeSBarry Smith @*/
5615c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
5625c6c1daeSBarry Smith {
5635c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5645c6c1daeSBarry Smith   PetscMPIInt       rank;
565dd2fa690SBarry Smith   PetscInt          tab,intab = ascii->tab;
5665c6c1daeSBarry Smith   PetscErrorCode    ierr;
5675c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5683f08860eSBarry Smith   PetscBool         iascii;
5695c6c1daeSBarry Smith   int               err;
5705c6c1daeSBarry Smith 
5715c6c1daeSBarry Smith   PetscFunctionBegin;
5725c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
573e5afcf28SBarry Smith   if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5745c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
5755c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
5765c6c1daeSBarry Smith   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
577ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
578559f443fSBarry Smith   if (rank) PetscFunctionReturn(0);
5793f08860eSBarry Smith 
5803f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5813f08860eSBarry Smith     char        *string;
5823f08860eSBarry Smith     va_list     Argp;
5833f08860eSBarry Smith     size_t      fullLength;
5843f08860eSBarry Smith 
5853f08860eSBarry Smith     ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
5863f08860eSBarry Smith     va_start(Argp,format);
5871575c14dSBarry Smith     ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr);
5883f08860eSBarry Smith     va_end(Argp);
589559f443fSBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
5903f08860eSBarry Smith     ierr = PetscFree(string);CHKERRQ(ierr);
5913f08860eSBarry Smith   } else { /* write directly to file */
5925c6c1daeSBarry Smith     va_list Argp;
593559f443fSBarry Smith     /* flush my own messages that I may have queued up */
594559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
595559f443fSBarry Smith     PetscInt    i;
596559f443fSBarry Smith     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
597559f443fSBarry Smith       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
598559f443fSBarry Smith       previous = next;
599559f443fSBarry Smith       next     = next->next;
600559f443fSBarry Smith       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
601559f443fSBarry Smith       ierr     = PetscFree(previous);CHKERRQ(ierr);
602559f443fSBarry Smith     }
603559f443fSBarry Smith     ascii->petsc_printfqueue       = 0;
604559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
605dd2fa690SBarry Smith     tab = intab;
606a297a907SKarl Rupp     while (tab--) {
607a297a907SKarl Rupp       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
608a297a907SKarl Rupp     }
6095c6c1daeSBarry Smith 
6105c6c1daeSBarry Smith     va_start(Argp,format);
6115c6c1daeSBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
6125c6c1daeSBarry Smith     err  = fflush(fd);
6135c6c1daeSBarry Smith     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6145c6c1daeSBarry Smith     if (petsc_history) {
6155c6c1daeSBarry Smith       va_start(Argp,format);
616dd2fa690SBarry Smith       tab = intab;
617a297a907SKarl Rupp       while (tab--) {
618706d7a88SBarry Smith         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
619a297a907SKarl Rupp       }
6205c6c1daeSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
6215c6c1daeSBarry Smith       err  = fflush(petsc_history);
6225c6c1daeSBarry Smith       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6235c6c1daeSBarry Smith     }
6245c6c1daeSBarry Smith     va_end(Argp);
6255c6c1daeSBarry Smith   }
6265c6c1daeSBarry Smith   PetscFunctionReturn(0);
6275c6c1daeSBarry Smith }
6285c6c1daeSBarry Smith 
6295c6c1daeSBarry Smith /*@C
6305c6c1daeSBarry Smith      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
6315c6c1daeSBarry Smith 
6325c6c1daeSBarry Smith     Collective on PetscViewer
6335c6c1daeSBarry Smith 
6345c6c1daeSBarry Smith   Input Parameters:
6355c6c1daeSBarry Smith +  viewer - the PetscViewer; either ASCII or binary
6365c6c1daeSBarry Smith -  name - the name of the file it should use
6375c6c1daeSBarry Smith 
6385c6c1daeSBarry Smith     Level: advanced
6395c6c1daeSBarry Smith 
6405c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
6415c6c1daeSBarry Smith           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
6425c6c1daeSBarry Smith 
6435c6c1daeSBarry Smith @*/
6445c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
6455c6c1daeSBarry Smith {
6465c6c1daeSBarry Smith   PetscErrorCode ierr;
6472fbecc10SBarry Smith   char           b[PETSC_MAX_PATH_LEN];
6485c6c1daeSBarry Smith 
6495c6c1daeSBarry Smith   PetscFunctionBegin;
6505c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6515c6c1daeSBarry Smith   PetscValidCharPointer(name,2);
6522fbecc10SBarry Smith   ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,b,sizeof(b));CHKERRQ(ierr);
6532fbecc10SBarry Smith   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,b));CHKERRQ(ierr);
6545c6c1daeSBarry Smith   PetscFunctionReturn(0);
6555c6c1daeSBarry Smith }
6565c6c1daeSBarry Smith 
6575c6c1daeSBarry Smith /*@C
6585c6c1daeSBarry Smith      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
6595c6c1daeSBarry Smith 
6605c6c1daeSBarry Smith     Not Collective
6615c6c1daeSBarry Smith 
6625c6c1daeSBarry Smith   Input Parameter:
6635c6c1daeSBarry Smith .  viewer - the PetscViewer; either ASCII or binary
6645c6c1daeSBarry Smith 
6655c6c1daeSBarry Smith   Output Parameter:
6665c6c1daeSBarry Smith .  name - the name of the file it is using
6675c6c1daeSBarry Smith 
6685c6c1daeSBarry Smith     Level: advanced
6695c6c1daeSBarry Smith 
6705c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
6715c6c1daeSBarry Smith 
6725c6c1daeSBarry Smith @*/
6735c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
6745c6c1daeSBarry Smith {
6755c6c1daeSBarry Smith   PetscErrorCode ierr;
6765c6c1daeSBarry Smith 
6775c6c1daeSBarry Smith   PetscFunctionBegin;
6785c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6796e05b1faSLisandro Dalcin   PetscValidPointer(name,2);
680163d334eSBarry Smith   ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
6815c6c1daeSBarry Smith   PetscFunctionReturn(0);
6825c6c1daeSBarry Smith }
6835c6c1daeSBarry Smith 
6845c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
6855c6c1daeSBarry Smith {
6865c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6875c6c1daeSBarry Smith 
6885c6c1daeSBarry Smith   PetscFunctionBegin;
6895c6c1daeSBarry Smith   *name = vascii->filename;
6905c6c1daeSBarry Smith   PetscFunctionReturn(0);
6915c6c1daeSBarry Smith }
6925c6c1daeSBarry Smith 
6935c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
6945c6c1daeSBarry Smith {
6955c6c1daeSBarry Smith   PetscErrorCode    ierr;
6965c6c1daeSBarry Smith   size_t            len;
6975c6c1daeSBarry Smith   char              fname[PETSC_MAX_PATH_LEN],*gz;
6985c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6995c6c1daeSBarry Smith   PetscBool         isstderr,isstdout;
7005c6c1daeSBarry Smith   PetscMPIInt       rank;
7015c6c1daeSBarry Smith 
7025c6c1daeSBarry Smith   PetscFunctionBegin;
7035c6c1daeSBarry Smith   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
7045c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
7055c6c1daeSBarry Smith   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
7065c6c1daeSBarry Smith 
7075c6c1daeSBarry Smith   /* Is this file to be compressed */
7085c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
709a297a907SKarl Rupp 
7105c6c1daeSBarry Smith   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
7115c6c1daeSBarry Smith   if (gz) {
7125c6c1daeSBarry Smith     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
7135c6c1daeSBarry Smith     if (len == 3) {
71408fb59bfSBarry Smith       if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
7155c6c1daeSBarry Smith       *gz = 0;
7165c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
7175c6c1daeSBarry Smith     }
7185c6c1daeSBarry Smith   }
719ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
7205c6c1daeSBarry Smith   if (!rank) {
7215c6c1daeSBarry Smith     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
7225c6c1daeSBarry Smith     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
7235c6c1daeSBarry Smith     /* empty filename means stdout */
7245c6c1daeSBarry Smith     if (name[0] == 0)  isstdout = PETSC_TRUE;
7255c6c1daeSBarry Smith     if (isstderr)      vascii->fd = PETSC_STDERR;
7265c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
7275c6c1daeSBarry Smith     else {
7285c6c1daeSBarry Smith 
7295c6c1daeSBarry Smith 
7305c6c1daeSBarry Smith       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
7315c6c1daeSBarry Smith       switch (vascii->mode) {
7325c6c1daeSBarry Smith       case FILE_MODE_READ:
7335c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r");
7345c6c1daeSBarry Smith         break;
7355c6c1daeSBarry Smith       case FILE_MODE_WRITE:
7365c6c1daeSBarry Smith         vascii->fd = fopen(fname,"w");
7375c6c1daeSBarry Smith         break;
7385c6c1daeSBarry Smith       case FILE_MODE_APPEND:
7395c6c1daeSBarry Smith         vascii->fd = fopen(fname,"a");
7405c6c1daeSBarry Smith         break;
7415c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
7425c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
743a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
7445c6c1daeSBarry Smith         break;
7455c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
7465c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
7475c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
7485c6c1daeSBarry Smith         */
7495c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
750a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
751a297a907SKarl Rupp         else {
7525c6c1daeSBarry Smith           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
7535c6c1daeSBarry Smith         }
7545c6c1daeSBarry Smith         break;
7555c6c1daeSBarry Smith       default:
7565c6c1daeSBarry Smith         SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
7575c6c1daeSBarry Smith       }
7585c6c1daeSBarry Smith       if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
7595c6c1daeSBarry Smith     }
7605c6c1daeSBarry Smith   }
7615c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7625c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
7635c6c1daeSBarry Smith #endif
7645c6c1daeSBarry Smith   PetscFunctionReturn(0);
7655c6c1daeSBarry Smith }
7665c6c1daeSBarry Smith 
7673f08860eSBarry Smith PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
7685c6c1daeSBarry Smith {
7695c6c1daeSBarry Smith   PetscMPIInt       rank;
7705c6c1daeSBarry Smith   PetscErrorCode    ierr;
7715c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
7725c6c1daeSBarry Smith 
7735c6c1daeSBarry Smith   PetscFunctionBegin;
774e5afcf28SBarry Smith   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
7753f08860eSBarry Smith   if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
776e5afcf28SBarry Smith   /*
777e5afcf28SBarry Smith      The following line is a bug; but if it is removed the code won't work because it relies on this behavior. In particular
778e5afcf28SBarry Smith      this line causes the synchronized flush to occur when the viewer is destroyed (since the count never gets to zero)
779e5afcf28SBarry Smith      in some examples this displays information that otherwise would be lost
780e5afcf28SBarry Smith   */
7811575c14dSBarry Smith   ierr         = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
7823f08860eSBarry Smith   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
7835c6c1daeSBarry Smith   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
7841575c14dSBarry Smith   ierr         = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
7855c6c1daeSBarry Smith   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
7865c6c1daeSBarry Smith   ovascii->fd  = vascii->fd;
7875c6c1daeSBarry Smith   ovascii->tab = vascii->tab;
788ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7895c6c1daeSBarry Smith 
7905c6c1daeSBarry Smith   vascii->sviewer = *outviewer;
7915c6c1daeSBarry Smith 
7925c6c1daeSBarry Smith   (*outviewer)->format  = viewer->format;
7935c6c1daeSBarry Smith 
794ce94432eSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
7955c6c1daeSBarry Smith   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
7963f08860eSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
7975c6c1daeSBarry Smith   PetscFunctionReturn(0);
7985c6c1daeSBarry Smith }
7995c6c1daeSBarry Smith 
8003f08860eSBarry Smith PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
8015c6c1daeSBarry Smith {
8025c6c1daeSBarry Smith   PetscErrorCode    ierr;
8035c6c1daeSBarry Smith   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
8045c6c1daeSBarry Smith 
8055c6c1daeSBarry Smith   PetscFunctionBegin;
8061575c14dSBarry Smith   if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
8071575c14dSBarry Smith   if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
8085c6c1daeSBarry Smith 
809e5afcf28SBarry Smith   ascii->sviewer             = NULL;
8105c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
8115c6c1daeSBarry Smith   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
812e5afcf28SBarry Smith   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
8135c6c1daeSBarry Smith   PetscFunctionReturn(0);
8145c6c1daeSBarry Smith }
8155c6c1daeSBarry Smith 
8162bf49c77SBarry Smith PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
8172bf49c77SBarry Smith {
8182bf49c77SBarry Smith   PetscErrorCode    ierr;
8192bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
8202bf49c77SBarry Smith 
8212bf49c77SBarry Smith   PetscFunctionBegin;
8222bf49c77SBarry Smith   if (ascii->filename) {
8232bf49c77SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
8242bf49c77SBarry Smith   }
8252bf49c77SBarry Smith   PetscFunctionReturn(0);
8262bf49c77SBarry Smith }
8272bf49c77SBarry Smith 
8288556b5ebSBarry Smith /*MC
8298556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
8308556b5ebSBarry Smith 
8318556b5ebSBarry Smith 
8328556b5ebSBarry Smith .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
8338556b5ebSBarry Smith            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
8348556b5ebSBarry Smith            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
8358556b5ebSBarry Smith 
8361b266c99SBarry Smith   Level: beginner
8371b266c99SBarry Smith 
8388556b5ebSBarry Smith M*/
8398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
8405c6c1daeSBarry Smith {
8415c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
8425c6c1daeSBarry Smith   PetscErrorCode    ierr;
8435c6c1daeSBarry Smith 
8445c6c1daeSBarry Smith   PetscFunctionBegin;
845b00a9115SJed Brown   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
8465c6c1daeSBarry Smith   viewer->data = (void*)vascii;
8475c6c1daeSBarry Smith 
8485c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
8495c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
850559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
851559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
8522bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
8531d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
8545c6c1daeSBarry Smith 
8555c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
8565c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
8575c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
8585c6c1daeSBarry Smith   vascii->bviewer   = 0;
859dd2fa690SBarry Smith   vascii->subviewer = 0;
8605c6c1daeSBarry Smith   vascii->sviewer   = 0;
8615c6c1daeSBarry Smith   vascii->tab       = 0;
8625c6c1daeSBarry Smith   vascii->tab_store = 0;
8635c6c1daeSBarry Smith   vascii->filename  = 0;
8645c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8655c6c1daeSBarry Smith 
866bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
867bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
868bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
869bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
8705c6c1daeSBarry Smith   PetscFunctionReturn(0);
8715c6c1daeSBarry Smith }
8725c6c1daeSBarry Smith 
8735c6c1daeSBarry Smith /*@C
8745c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8755c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8765c6c1daeSBarry Smith     second, etc.
8775c6c1daeSBarry Smith 
8785c6c1daeSBarry Smith     Not Collective, must call collective PetscViewerFlush() to get the results out
8795c6c1daeSBarry Smith 
8805c6c1daeSBarry Smith     Input Parameters:
8815c6c1daeSBarry Smith +   viewer - the ASCII PetscViewer
8825c6c1daeSBarry Smith -   format - the usual printf() format string
8835c6c1daeSBarry Smith 
8845c6c1daeSBarry Smith     Level: intermediate
8855c6c1daeSBarry Smith 
88695452b02SPatrick Sanan     Notes:
88795452b02SPatrick Sanan     You must have previously called PetscViewerASCIISynchronizeAllow() to allow this routine to be called.
8885c6c1daeSBarry Smith 
8895c6c1daeSBarry Smith     Fortran Note:
8905c6c1daeSBarry Smith       Can only print a single character* string
8915c6c1daeSBarry Smith 
8925c6c1daeSBarry Smith .seealso: PetscSynchronizedPrintf(), PetscSynchronizedFlush(), PetscFPrintf(),
8935c6c1daeSBarry Smith           PetscFOpen(), PetscViewerFlush(), PetscViewerASCIIGetPointer(), PetscViewerDestroy(), PetscViewerASCIIOpen(),
8941575c14dSBarry Smith           PetscViewerASCIIPrintf(), PetscViewerASCIIPushSynchronized()
8955c6c1daeSBarry Smith 
8965c6c1daeSBarry Smith @*/
8975c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
8985c6c1daeSBarry Smith {
8995c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
9005c6c1daeSBarry Smith   PetscErrorCode    ierr;
9013f08860eSBarry Smith   PetscMPIInt       rank;
9025c6c1daeSBarry Smith   PetscInt          tab = vascii->tab;
9035c6c1daeSBarry Smith   MPI_Comm          comm;
9045c6c1daeSBarry Smith   FILE              *fp;
905559f443fSBarry Smith   PetscBool         iascii,hasbviewer = PETSC_FALSE;
9065c6c1daeSBarry Smith   int               err;
9075c6c1daeSBarry Smith 
9085c6c1daeSBarry Smith   PetscFunctionBegin;
9095c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
9105c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
9115c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
9125c6c1daeSBarry Smith   if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
9131575c14dSBarry Smith   if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
9145c6c1daeSBarry Smith 
915ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
9165c6c1daeSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
9175c6c1daeSBarry Smith 
918559f443fSBarry Smith   if (vascii->bviewer) {
919559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
920559f443fSBarry Smith     if (!rank) {
921559f443fSBarry Smith       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
922559f443fSBarry Smith       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
923559f443fSBarry Smith       ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
924559f443fSBarry Smith     }
925559f443fSBarry Smith   }
9263f08860eSBarry Smith 
927559f443fSBarry Smith   fp   = vascii->fd;
928559f443fSBarry Smith 
929559f443fSBarry Smith   if (!rank && !hasbviewer) {   /* First processor prints immediately to fp */
9305c6c1daeSBarry Smith     va_list Argp;
931559f443fSBarry Smith     /* flush my own messages that I may have queued up */
932559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
933559f443fSBarry Smith     PetscInt    i;
934559f443fSBarry Smith     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
935559f443fSBarry Smith       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
936559f443fSBarry Smith       previous = next;
937559f443fSBarry Smith       next     = next->next;
938559f443fSBarry Smith       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
939559f443fSBarry Smith       ierr     = PetscFree(previous);CHKERRQ(ierr);
940559f443fSBarry Smith     }
941559f443fSBarry Smith     vascii->petsc_printfqueue       = 0;
942559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
9435c6c1daeSBarry Smith 
944a297a907SKarl Rupp     while (tab--) {
945a297a907SKarl Rupp       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
946a297a907SKarl Rupp     }
9475c6c1daeSBarry Smith 
9485c6c1daeSBarry Smith     va_start(Argp,format);
9495c6c1daeSBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
9505c6c1daeSBarry Smith     err  = fflush(fp);
9515c6c1daeSBarry Smith     if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9525c6c1daeSBarry Smith     if (petsc_history) {
9535c6c1daeSBarry Smith       va_start(Argp,format);
9545c6c1daeSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
9555c6c1daeSBarry Smith       err  = fflush(petsc_history);
9565c6c1daeSBarry Smith       if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9575c6c1daeSBarry Smith     }
9585c6c1daeSBarry Smith     va_end(Argp);
959559f443fSBarry Smith   } else { /* other processors add to queue */
9605c6c1daeSBarry Smith     char        *string;
9615c6c1daeSBarry Smith     va_list     Argp;
9625c6c1daeSBarry Smith     size_t      fullLength;
9635c6c1daeSBarry Smith     PrintfQueue next;
9645c6c1daeSBarry Smith 
965b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
966559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
967559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
968559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
969a297a907SKarl Rupp     } else {
970559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
971a297a907SKarl Rupp     }
972559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9735c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
974*580bdb30SBarry Smith     ierr       = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
9755c6c1daeSBarry Smith     string     = next->string;
9765c6c1daeSBarry Smith     tab       *= 2;
977a297a907SKarl Rupp     while (tab--) {
978a297a907SKarl Rupp       *string++ = ' ';
979a297a907SKarl Rupp     }
9805c6c1daeSBarry Smith     va_start(Argp,format);
98122d28d08SBarry Smith     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
9825c6c1daeSBarry Smith     va_end(Argp);
983cb500232SBarry Smith     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
98414416c0eSBarry Smith       ierr       = PetscFree(next->string);CHKERRQ(ierr);
98514416c0eSBarry Smith       next->size = fullLength + 2*vascii->tab;
986*580bdb30SBarry Smith       ierr       = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
98714416c0eSBarry Smith       string     = next->string;
98814416c0eSBarry Smith       tab        = 2*vascii->tab;
98914416c0eSBarry Smith       while (tab--) {
99014416c0eSBarry Smith         *string++ = ' ';
99114416c0eSBarry Smith       }
99214416c0eSBarry Smith       va_start(Argp,format);
99314416c0eSBarry Smith       ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr);
99414416c0eSBarry Smith       va_end(Argp);
99514416c0eSBarry Smith     }
9965c6c1daeSBarry Smith   }
9975c6c1daeSBarry Smith   PetscFunctionReturn(0);
9985c6c1daeSBarry Smith }
9995c6c1daeSBarry Smith 
10002655f987SMichael Lange /*@C
1001f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
10022655f987SMichael Lange 
1003f8859db6SBarry Smith    Only process 0 in the PetscViewer may call this
10042655f987SMichael Lange 
10052655f987SMichael Lange    Input Parameters:
10062655f987SMichael Lange +  viewer - the ascii viewer
10072655f987SMichael Lange .  data - location to write the data
1008060da220SMatthew G. Knepley .  num - number of items of data to read
10092655f987SMichael Lange -  datatype - type of data to read
10102655f987SMichael Lange 
1011f8e4bde8SMatthew G. Knepley    Output Parameters:
1012060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
1013f8e4bde8SMatthew G. Knepley 
10142655f987SMichael Lange    Level: beginner
10152655f987SMichael Lange 
1016f8859db6SBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
10172655f987SMichael Lange           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
101805119932SBarry Smith           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
10192655f987SMichael Lange @*/
1020060da220SMatthew G. Knepley PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
10212655f987SMichael Lange {
10222655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
10232655f987SMichael Lange   FILE              *fd = vascii->fd;
10242655f987SMichael Lange   PetscInt           i;
10253b7fe8c3SMatthew G. Knepley   int                ret = 0;
1026f8859db6SBarry Smith   PetscMPIInt        rank;
1027f8859db6SBarry Smith   PetscErrorCode     ierr;
10282655f987SMichael Lange 
10292655f987SMichael Lange   PetscFunctionBegin;
10302655f987SMichael Lange   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1031f8859db6SBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1032f8859db6SBarry Smith   if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1033060da220SMatthew G. Knepley   for (i=0; i<num; i++) {
1034f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1035f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1036a05e1a72SSatish Balay     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1037f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
10389e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1039972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1040f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1041f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1042a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
1043fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
1044fba955ccSBarry Smith       double tmp;
1045fba955ccSBarry Smith       ret = fscanf(fd, "%lg", &tmp);
1046a6e181c6SToby Isaac       ((__float128*)data)[i] = tmp;
1047a6e181c6SToby Isaac     }
1048fba955ccSBarry Smith #endif
1049f8e4bde8SMatthew G. Knepley     else {SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);}
1050f8e4bde8SMatthew G. Knepley     if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1051f8e4bde8SMatthew G. Knepley     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10522655f987SMichael Lange   }
1053060da220SMatthew G. Knepley   if (count) *count = i;
1054060da220SMatthew G. Knepley   else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
10552655f987SMichael Lange   PetscFunctionReturn(0);
10562655f987SMichael Lange }
10575c6c1daeSBarry Smith 
1058