xref: /petsc/src/sys/classes/viewer/impls/ascii/filev.c (revision 2c71b3e237ead271e4f3aa1505f92bf476e3413d)
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;
14*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
15ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr);
16dd400576SPatrick Sanan   if (rank == 0 && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
175c6c1daeSBarry Smith     if (vascii->fd && vascii->closefile) {
185c6c1daeSBarry Smith       err = fclose(vascii->fd);
19*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(err,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);
28*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(fgets(buf,1024,fp),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;
48*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(vascii->sviewer,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) {
54ffc4695bSBarry Smith     ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRMPI(ierr);
555c6c1daeSBarry Smith   }
565c6c1daeSBarry Smith 
57ffc4695bSBarry Smith   ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRMPI(ierr);
585c6c1daeSBarry Smith   if (flg) {
595c6c1daeSBarry Smith     if (vlink && vlink->viewer == viewer) {
60e5840a18SBarry Smith       if (vlink->next) {
61ffc4695bSBarry Smith         ierr = MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRMPI(ierr);
62e5840a18SBarry Smith       } else {
63ffc4695bSBarry Smith         ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);CHKERRMPI(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;
80ffc4695bSBarry Smith     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRMPI(ierr);
81aa139df6SJed Brown     if (flg && aviewer == viewer) {
82ffc4695bSBarry Smith       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);CHKERRMPI(ierr);
83aa139df6SJed Brown     }
84aa139df6SJed Brown   }
85aa139df6SJed Brown   if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
86aa139df6SJed Brown     PetscViewer aviewer;
87ffc4695bSBarry Smith     ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRMPI(ierr);
88aa139df6SJed Brown     if (flg && aviewer == viewer) {
89ffc4695bSBarry Smith       ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);CHKERRMPI(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;
115*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(vascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
116559f443fSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
117ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
118ffc4695bSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr);
119559f443fSBarry Smith 
120dd400576SPatrick Sanan   if (!vascii->bviewer && rank == 0 && (vascii->mode != FILE_MODE_READ)) {
1215c6c1daeSBarry Smith     err = fflush(vascii->fd);
122*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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 
130559f443fSBarry Smith     ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
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) {
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       }
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 */
151ffc4695bSBarry Smith         ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRMPI(ierr);
152ffc4695bSBarry Smith         ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRMPI(ierr);
153559f443fSBarry Smith         for (j=0; j<n; j++) {
154559f443fSBarry Smith           PetscMPIInt size = 0;
155559f443fSBarry Smith 
156ffc4695bSBarry Smith           ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRMPI(ierr);
157559f443fSBarry Smith           ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
158ffc4695bSBarry Smith           ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRMPI(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 
170ffc4695bSBarry Smith       ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRMPI(ierr);
171ffc4695bSBarry Smith       ierr = MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRMPI(ierr);
172559f443fSBarry Smith       for (i=0; i<vascii->petsc_printfqueuelength; i++) {
17355b25c41SPierre Jolivet         ierr     = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRMPI(ierr);
17455b25c41SPierre Jolivet         ierr     = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRMPI(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       }
18002c9f0b5SLisandro Dalcin       vascii->petsc_printfqueue       = NULL;
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 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
2075c6c1daeSBarry Smith           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 
2565c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
2575c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2585c6c1daeSBarry Smith           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   PetscErrorCode    ierr;
2655c6c1daeSBarry Smith 
2665c6c1daeSBarry Smith   PetscFunctionBegin;
2675c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
2685c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
269a297a907SKarl Rupp   if (iascii) ascii->tab = tabs;
2705c6c1daeSBarry Smith   PetscFunctionReturn(0);
2715c6c1daeSBarry Smith }
2725c6c1daeSBarry Smith 
2735c6c1daeSBarry Smith /*@
2745c6c1daeSBarry Smith     PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
2755c6c1daeSBarry Smith 
2765c6c1daeSBarry Smith     Not Collective, meaningful on first processor only.
2775c6c1daeSBarry Smith 
2785c6c1daeSBarry Smith     Input Parameters:
2791575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
280a2b725a8SWilliam Gropp 
2815c6c1daeSBarry Smith     Output Parameters:
2825c6c1daeSBarry Smith .    tabs - number of tabs
2835c6c1daeSBarry Smith 
2845c6c1daeSBarry Smith     Level: developer
2855c6c1daeSBarry Smith 
2865c6c1daeSBarry Smith     Fortran Note:
2875c6c1daeSBarry Smith     This routine is not supported in Fortran.
2885c6c1daeSBarry Smith 
2895c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
2905c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
2915c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
2925c6c1daeSBarry Smith @*/
2935c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
2945c6c1daeSBarry Smith {
2955c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
2965c6c1daeSBarry Smith   PetscBool         iascii;
2975c6c1daeSBarry Smith   PetscErrorCode    ierr;
2985c6c1daeSBarry Smith 
2995c6c1daeSBarry Smith   PetscFunctionBegin;
3005c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3015c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
302a297a907SKarl Rupp   if (iascii && tabs) *tabs = ascii->tab;
3035c6c1daeSBarry Smith   PetscFunctionReturn(0);
3045c6c1daeSBarry Smith }
3055c6c1daeSBarry Smith 
3065c6c1daeSBarry Smith /*@
3075c6c1daeSBarry Smith     PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
3085c6c1daeSBarry Smith 
3095c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3105c6c1daeSBarry Smith 
3115c6c1daeSBarry Smith     Input Parameters:
3121575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3135c6c1daeSBarry Smith -    tabs - number of tabs
3145c6c1daeSBarry Smith 
3155c6c1daeSBarry Smith     Level: developer
3165c6c1daeSBarry Smith 
3175c6c1daeSBarry Smith     Fortran Note:
3185c6c1daeSBarry Smith     This routine is not supported in Fortran.
3195c6c1daeSBarry Smith 
3205c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3215c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3225c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3235c6c1daeSBarry Smith @*/
3245c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
3255c6c1daeSBarry Smith {
3265c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3275c6c1daeSBarry Smith   PetscBool         iascii;
3285c6c1daeSBarry Smith   PetscErrorCode    ierr;
3295c6c1daeSBarry Smith 
3305c6c1daeSBarry Smith   PetscFunctionBegin;
3315c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3325c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
333a297a907SKarl Rupp   if (iascii) ascii->tab += tabs;
3345c6c1daeSBarry Smith   PetscFunctionReturn(0);
3355c6c1daeSBarry Smith }
3365c6c1daeSBarry Smith 
3375c6c1daeSBarry Smith /*@
3385c6c1daeSBarry Smith     PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
3415c6c1daeSBarry Smith 
3425c6c1daeSBarry Smith     Input Parameters:
3431575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
3445c6c1daeSBarry Smith -    tabs - number of tabs
3455c6c1daeSBarry Smith 
3465c6c1daeSBarry Smith     Level: developer
3475c6c1daeSBarry Smith 
3485c6c1daeSBarry Smith     Fortran Note:
3495c6c1daeSBarry Smith     This routine is not supported in Fortran.
3505c6c1daeSBarry Smith 
3515c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
3525c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
3535c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
3545c6c1daeSBarry Smith @*/
3555c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
3565c6c1daeSBarry Smith {
3575c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3585c6c1daeSBarry Smith   PetscBool         iascii;
3595c6c1daeSBarry Smith   PetscErrorCode    ierr;
3605c6c1daeSBarry Smith 
3615c6c1daeSBarry Smith   PetscFunctionBegin;
3625c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
3635c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
364a297a907SKarl Rupp   if (iascii) ascii->tab -= tabs;
3655c6c1daeSBarry Smith   PetscFunctionReturn(0);
3665c6c1daeSBarry Smith }
3675c6c1daeSBarry Smith 
3685c6c1daeSBarry Smith /*@C
3691575c14dSBarry Smith     PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
3705c6c1daeSBarry Smith 
3715c6c1daeSBarry Smith     Collective on PetscViewer
3725c6c1daeSBarry Smith 
3735c6c1daeSBarry Smith     Input Parameters:
3741575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
3755c6c1daeSBarry Smith 
3765c6c1daeSBarry Smith     Level: intermediate
3775c6c1daeSBarry Smith 
378e6abc3ddSVáclav Hapla     Notes:
379e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
3805c6c1daeSBarry Smith 
381e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
382e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
383e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
3845c6c1daeSBarry Smith @*/
3851575c14dSBarry Smith PetscErrorCode  PetscViewerASCIIPushSynchronized(PetscViewer viewer)
3865c6c1daeSBarry Smith {
3875c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
3885c6c1daeSBarry Smith   PetscBool         iascii;
3895c6c1daeSBarry Smith   PetscErrorCode    ierr;
3905c6c1daeSBarry Smith 
3915c6c1daeSBarry Smith   PetscFunctionBegin;
3925c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
393*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
3945c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
3951575c14dSBarry Smith   if (iascii) ascii->allowsynchronized++;
3961575c14dSBarry Smith   PetscFunctionReturn(0);
3971575c14dSBarry Smith }
3981575c14dSBarry Smith 
3991575c14dSBarry Smith /*@C
4001575c14dSBarry Smith     PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
4011575c14dSBarry Smith 
4021575c14dSBarry Smith     Collective on PetscViewer
4031575c14dSBarry Smith 
4041575c14dSBarry Smith     Input Parameters:
4051575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4061575c14dSBarry Smith 
4071575c14dSBarry Smith     Level: intermediate
4081575c14dSBarry Smith 
409e6abc3ddSVáclav Hapla     Notes:
410e6abc3ddSVáclav Hapla     See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
4111575c14dSBarry Smith 
412e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
413e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
414e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
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);
424*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ascii->sviewer,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--;
428*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(ascii->allowsynchronized < 0,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 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4485c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4495c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4505c6c1daeSBarry Smith @*/
4515c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPushTab(PetscViewer viewer)
4525c6c1daeSBarry Smith {
4535c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4545c6c1daeSBarry Smith   PetscBool         iascii;
4555c6c1daeSBarry Smith   PetscErrorCode    ierr;
4565c6c1daeSBarry Smith 
4575c6c1daeSBarry Smith   PetscFunctionBegin;
4585c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4595c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
460a297a907SKarl Rupp   if (iascii) ascii->tab++;
4615c6c1daeSBarry Smith   PetscFunctionReturn(0);
4625c6c1daeSBarry Smith }
4635c6c1daeSBarry Smith 
4641c297824SMatthew G. Knepley /*@C
4655c6c1daeSBarry Smith     PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
4665c6c1daeSBarry Smith      lines are tabbed.
4675c6c1daeSBarry Smith 
4685c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
4695c6c1daeSBarry Smith 
4705c6c1daeSBarry Smith     Input Parameters:
4711575c14dSBarry Smith .    viewer - obtained with PetscViewerASCIIOpen()
4725c6c1daeSBarry Smith 
4735c6c1daeSBarry Smith     Level: developer
4745c6c1daeSBarry Smith 
4755c6c1daeSBarry Smith     Fortran Note:
4765c6c1daeSBarry Smith     This routine is not supported in Fortran.
4775c6c1daeSBarry Smith 
4785c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
4795c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
4805c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
4815c6c1daeSBarry Smith @*/
4825c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPopTab(PetscViewer viewer)
4835c6c1daeSBarry Smith {
4845c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
4855c6c1daeSBarry Smith   PetscErrorCode    ierr;
4865c6c1daeSBarry Smith   PetscBool         iascii;
4875c6c1daeSBarry Smith 
4885c6c1daeSBarry Smith   PetscFunctionBegin;
4895c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
4905c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
4915c6c1daeSBarry Smith   if (iascii) {
492*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(ascii->tab <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
4935c6c1daeSBarry Smith     ascii->tab--;
4945c6c1daeSBarry Smith   }
4955c6c1daeSBarry Smith   PetscFunctionReturn(0);
4965c6c1daeSBarry Smith }
4975c6c1daeSBarry Smith 
4985c6c1daeSBarry Smith /*@
4995c6c1daeSBarry Smith     PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
5005c6c1daeSBarry Smith 
5015c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5025c6c1daeSBarry Smith 
5035c6c1daeSBarry Smith     Input Parameters:
5041575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5055c6c1daeSBarry Smith -    flg - PETSC_TRUE or PETSC_FALSE
5065c6c1daeSBarry Smith 
5075c6c1daeSBarry Smith     Level: developer
5085c6c1daeSBarry Smith 
5095c6c1daeSBarry Smith     Fortran Note:
5105c6c1daeSBarry Smith     This routine is not supported in Fortran.
5115c6c1daeSBarry Smith 
5125c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
5135c6c1daeSBarry Smith           PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
5145c6c1daeSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
5155c6c1daeSBarry Smith @*/
5165c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
5175c6c1daeSBarry Smith {
5185c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5195c6c1daeSBarry Smith   PetscBool         iascii;
5205c6c1daeSBarry Smith   PetscErrorCode    ierr;
5215c6c1daeSBarry Smith 
5225c6c1daeSBarry Smith   PetscFunctionBegin;
5235c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
5245c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
5255c6c1daeSBarry Smith   if (iascii) {
526a297a907SKarl Rupp     if (flg) ascii->tab = ascii->tab_store;
527a297a907SKarl Rupp     else {
5285c6c1daeSBarry Smith       ascii->tab_store = ascii->tab;
5295c6c1daeSBarry Smith       ascii->tab       = 0;
5305c6c1daeSBarry Smith     }
5315c6c1daeSBarry Smith   }
5325c6c1daeSBarry Smith   PetscFunctionReturn(0);
5335c6c1daeSBarry Smith }
5345c6c1daeSBarry Smith 
5355c6c1daeSBarry Smith /* ----------------------------------------------------------------------- */
5365c6c1daeSBarry Smith 
5375c6c1daeSBarry Smith /*@C
5385c6c1daeSBarry Smith     PetscViewerASCIIPrintf - Prints to a file, only from the first
5395c6c1daeSBarry Smith     processor in the PetscViewer
5405c6c1daeSBarry Smith 
5415c6c1daeSBarry Smith     Not Collective, but only first processor in set has any effect
5425c6c1daeSBarry Smith 
5435c6c1daeSBarry Smith     Input Parameters:
5441575c14dSBarry Smith +    viewer - obtained with PetscViewerASCIIOpen()
5455c6c1daeSBarry Smith -    format - the usual printf() format string
5465c6c1daeSBarry Smith 
5475c6c1daeSBarry Smith     Level: developer
5485c6c1daeSBarry Smith 
5495c6c1daeSBarry Smith     Fortran Note:
5505c6c1daeSBarry Smith     The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
5515c6c1daeSBarry Smith     That is, you can only pass a single character string from Fortran.
5525c6c1daeSBarry Smith 
5535c6c1daeSBarry Smith .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
5545c6c1daeSBarry Smith           PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
5551575c14dSBarry Smith           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
5565c6c1daeSBarry Smith @*/
5575c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
5585c6c1daeSBarry Smith {
5595c6c1daeSBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
5605c6c1daeSBarry Smith   PetscMPIInt       rank;
561dd2fa690SBarry Smith   PetscInt          tab,intab = ascii->tab;
5625c6c1daeSBarry Smith   PetscErrorCode    ierr;
5635c6c1daeSBarry Smith   FILE              *fd = ascii->fd;
5643f08860eSBarry Smith   PetscBool         iascii;
5655c6c1daeSBarry Smith   int               err;
5665c6c1daeSBarry Smith 
5675c6c1daeSBarry Smith   PetscFunctionBegin;
5685c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
569*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ascii->sviewer,PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
5705c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
5715c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
572*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
573ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr);
574559f443fSBarry Smith   if (rank) PetscFunctionReturn(0);
5753f08860eSBarry Smith 
5763f08860eSBarry Smith   if (ascii->bviewer) { /* pass string up to parent viewer */
5773f08860eSBarry Smith     char        *string;
5783f08860eSBarry Smith     va_list     Argp;
5793f08860eSBarry Smith     size_t      fullLength;
5803f08860eSBarry Smith 
5813f08860eSBarry Smith     ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
5823f08860eSBarry Smith     va_start(Argp,format);
5831575c14dSBarry Smith     ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr);
5843f08860eSBarry Smith     va_end(Argp);
585559f443fSBarry Smith     ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
5863f08860eSBarry Smith     ierr = PetscFree(string);CHKERRQ(ierr);
5873f08860eSBarry Smith   } else { /* write directly to file */
5885c6c1daeSBarry Smith     va_list Argp;
589559f443fSBarry Smith     /* flush my own messages that I may have queued up */
590559f443fSBarry Smith     PrintfQueue next = ascii->petsc_printfqueuebase,previous;
591559f443fSBarry Smith     PetscInt    i;
592559f443fSBarry Smith     for (i=0; i<ascii->petsc_printfqueuelength; i++) {
593559f443fSBarry Smith       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
594559f443fSBarry Smith       previous = next;
595559f443fSBarry Smith       next     = next->next;
596559f443fSBarry Smith       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
597559f443fSBarry Smith       ierr     = PetscFree(previous);CHKERRQ(ierr);
598559f443fSBarry Smith     }
59902c9f0b5SLisandro Dalcin     ascii->petsc_printfqueue       = NULL;
600559f443fSBarry Smith     ascii->petsc_printfqueuelength = 0;
601dd2fa690SBarry Smith     tab = intab;
602a297a907SKarl Rupp     while (tab--) {
603a297a907SKarl Rupp       ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"  ");CHKERRQ(ierr);
604a297a907SKarl Rupp     }
6055c6c1daeSBarry Smith 
6065c6c1daeSBarry Smith     va_start(Argp,format);
6075c6c1daeSBarry Smith     ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
6085c6c1daeSBarry Smith     err  = fflush(fd);
609*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6105c6c1daeSBarry Smith     if (petsc_history) {
6115c6c1daeSBarry Smith       va_start(Argp,format);
612dd2fa690SBarry Smith       tab = intab;
613a297a907SKarl Rupp       while (tab--) {
614706d7a88SBarry Smith         ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history,"  ");CHKERRQ(ierr);
615a297a907SKarl Rupp       }
6165c6c1daeSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
6175c6c1daeSBarry Smith       err  = fflush(petsc_history);
618*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
6195c6c1daeSBarry Smith     }
6205c6c1daeSBarry Smith     va_end(Argp);
6215c6c1daeSBarry Smith   }
6225c6c1daeSBarry Smith   PetscFunctionReturn(0);
6235c6c1daeSBarry Smith }
6245c6c1daeSBarry Smith 
6255c6c1daeSBarry Smith /*@C
6265c6c1daeSBarry Smith      PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
6275c6c1daeSBarry Smith 
6285c6c1daeSBarry Smith     Collective on PetscViewer
6295c6c1daeSBarry Smith 
6305c6c1daeSBarry Smith   Input Parameters:
6315c6c1daeSBarry Smith +  viewer - the PetscViewer; either ASCII or binary
6325c6c1daeSBarry Smith -  name - the name of the file it should use
6335c6c1daeSBarry Smith 
6345c6c1daeSBarry Smith     Level: advanced
6355c6c1daeSBarry Smith 
6365c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
6375c6c1daeSBarry Smith           PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
6385c6c1daeSBarry Smith 
6395c6c1daeSBarry Smith @*/
6405c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName(PetscViewer viewer,const char name[])
6415c6c1daeSBarry Smith {
6425c6c1daeSBarry Smith   PetscErrorCode ierr;
643cc843e7aSLisandro Dalcin   char           filename[PETSC_MAX_PATH_LEN];
6445c6c1daeSBarry Smith 
6455c6c1daeSBarry Smith   PetscFunctionBegin;
6465c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6475c6c1daeSBarry Smith   PetscValidCharPointer(name,2);
648cc843e7aSLisandro Dalcin   ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));CHKERRQ(ierr);
649cc843e7aSLisandro Dalcin   ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));CHKERRQ(ierr);
6505c6c1daeSBarry Smith   PetscFunctionReturn(0);
6515c6c1daeSBarry Smith }
6525c6c1daeSBarry Smith 
6535c6c1daeSBarry Smith /*@C
6545c6c1daeSBarry Smith      PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
6555c6c1daeSBarry Smith 
6565c6c1daeSBarry Smith     Not Collective
6575c6c1daeSBarry Smith 
6585c6c1daeSBarry Smith   Input Parameter:
6595c6c1daeSBarry Smith .  viewer - the PetscViewer; either ASCII or binary
6605c6c1daeSBarry Smith 
6615c6c1daeSBarry Smith   Output Parameter:
6625c6c1daeSBarry Smith .  name - the name of the file it is using
6635c6c1daeSBarry Smith 
6645c6c1daeSBarry Smith     Level: advanced
6655c6c1daeSBarry Smith 
6665c6c1daeSBarry Smith .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
6675c6c1daeSBarry Smith 
6685c6c1daeSBarry Smith @*/
6695c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName(PetscViewer viewer,const char **name)
6705c6c1daeSBarry Smith {
6715c6c1daeSBarry Smith   PetscErrorCode ierr;
6725c6c1daeSBarry Smith 
6735c6c1daeSBarry Smith   PetscFunctionBegin;
6745c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
6756e05b1faSLisandro Dalcin   PetscValidPointer(name,2);
676163d334eSBarry Smith   ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
6775c6c1daeSBarry Smith   PetscFunctionReturn(0);
6785c6c1daeSBarry Smith }
6795c6c1daeSBarry Smith 
6805c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
6815c6c1daeSBarry Smith {
6825c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6835c6c1daeSBarry Smith 
6845c6c1daeSBarry Smith   PetscFunctionBegin;
6855c6c1daeSBarry Smith   *name = vascii->filename;
6865c6c1daeSBarry Smith   PetscFunctionReturn(0);
6875c6c1daeSBarry Smith }
6885c6c1daeSBarry Smith 
6895c6c1daeSBarry Smith PetscErrorCode  PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
6905c6c1daeSBarry Smith {
6915c6c1daeSBarry Smith   PetscErrorCode    ierr;
6925c6c1daeSBarry Smith   size_t            len;
6935c6c1daeSBarry Smith   char              fname[PETSC_MAX_PATH_LEN],*gz;
6945c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
6955c6c1daeSBarry Smith   PetscBool         isstderr,isstdout;
6965c6c1daeSBarry Smith   PetscMPIInt       rank;
6975c6c1daeSBarry Smith 
6985c6c1daeSBarry Smith   PetscFunctionBegin;
6995c6c1daeSBarry Smith   ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
7005c6c1daeSBarry Smith   if (!name) PetscFunctionReturn(0);
7015c6c1daeSBarry Smith   ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
7025c6c1daeSBarry Smith 
7035c6c1daeSBarry Smith   /* Is this file to be compressed */
7045c6c1daeSBarry Smith   vascii->storecompressed = PETSC_FALSE;
705a297a907SKarl Rupp 
7065c6c1daeSBarry Smith   ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
7075c6c1daeSBarry Smith   if (gz) {
7085c6c1daeSBarry Smith     ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
7095c6c1daeSBarry Smith     if (len == 3) {
710*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(vascii->mode != FILE_MODE_WRITE,PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
7115c6c1daeSBarry Smith       *gz = 0;
7125c6c1daeSBarry Smith       vascii->storecompressed = PETSC_TRUE;
7135c6c1daeSBarry Smith     }
7145c6c1daeSBarry Smith   }
715ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr);
716dd400576SPatrick Sanan   if (rank == 0) {
7175c6c1daeSBarry Smith     ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
7185c6c1daeSBarry Smith     ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
7195c6c1daeSBarry Smith     /* empty filename means stdout */
7205c6c1daeSBarry Smith     if (name[0] == 0)  isstdout = PETSC_TRUE;
7215c6c1daeSBarry Smith     if (isstderr)      vascii->fd = PETSC_STDERR;
7225c6c1daeSBarry Smith     else if (isstdout) vascii->fd = PETSC_STDOUT;
7235c6c1daeSBarry Smith     else {
7245c6c1daeSBarry Smith 
7255c6c1daeSBarry Smith       ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
7265c6c1daeSBarry Smith       switch (vascii->mode) {
7275c6c1daeSBarry Smith       case FILE_MODE_READ:
7285c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r");
7295c6c1daeSBarry Smith         break;
7305c6c1daeSBarry Smith       case FILE_MODE_WRITE:
7315c6c1daeSBarry Smith         vascii->fd = fopen(fname,"w");
7325c6c1daeSBarry Smith         break;
7335c6c1daeSBarry Smith       case FILE_MODE_APPEND:
7345c6c1daeSBarry Smith         vascii->fd = fopen(fname,"a");
7355c6c1daeSBarry Smith         break;
7365c6c1daeSBarry Smith       case FILE_MODE_UPDATE:
7375c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
738a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
7395c6c1daeSBarry Smith         break;
7405c6c1daeSBarry Smith       case FILE_MODE_APPEND_UPDATE:
7415c6c1daeSBarry Smith         /* I really want a file which is opened at the end for updating,
7425c6c1daeSBarry Smith            not a+, which opens at the beginning, but makes writes at the end.
7435c6c1daeSBarry Smith         */
7445c6c1daeSBarry Smith         vascii->fd = fopen(fname,"r+");
745a297a907SKarl Rupp         if (!vascii->fd) vascii->fd = fopen(fname,"w+");
746a297a907SKarl Rupp         else {
7475c6c1daeSBarry Smith           ierr     = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
7485c6c1daeSBarry Smith         }
7495c6c1daeSBarry Smith         break;
7505c6c1daeSBarry Smith       default:
75198921bdaSJacob Faibussowitsch         SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vascii->mode]);
7525c6c1daeSBarry Smith       }
753*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(!vascii->fd,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
7545c6c1daeSBarry Smith     }
7555c6c1daeSBarry Smith   }
7565c6c1daeSBarry Smith #if defined(PETSC_USE_LOG)
7575c6c1daeSBarry Smith   PetscLogObjectState((PetscObject)viewer,"File: %s",name);
7585c6c1daeSBarry Smith #endif
7595c6c1daeSBarry Smith   PetscFunctionReturn(0);
7605c6c1daeSBarry Smith }
7615c6c1daeSBarry Smith 
7623f08860eSBarry Smith PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
7635c6c1daeSBarry Smith {
7645c6c1daeSBarry Smith   PetscErrorCode    ierr;
7655c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
7665c6c1daeSBarry Smith 
7675c6c1daeSBarry Smith   PetscFunctionBegin;
768e5afcf28SBarry Smith   ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
769*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(vascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
770e5afcf28SBarry Smith   /*
7719530cbd7SBarry Smith      The following line is a bug; it does another PetscViewerASCIIPushSynchronized() on viewer, but if it is removed the code won't work
7729530cbd7SBarry 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
7739530cbd7SBarry Smith      (since the count never gets to zero) in some examples this displays information that otherwise would be lost
7749530cbd7SBarry Smith 
7759530cbd7SBarry Smith      This code also means another call to PetscViewerASCIIPopSynchronized() must be made after the PetscViewerRestoreSubViewer(), see, for example,
7769530cbd7SBarry Smith      PCView_GASM().
777e5afcf28SBarry Smith   */
7781575c14dSBarry Smith   ierr         = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
7793f08860eSBarry Smith   ierr         = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
7805c6c1daeSBarry Smith   ierr         = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
7811575c14dSBarry Smith   ierr         = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
7825c6c1daeSBarry Smith   ovascii      = (PetscViewer_ASCII*)(*outviewer)->data;
7835c6c1daeSBarry Smith   ovascii->fd  = vascii->fd;
7845c6c1daeSBarry Smith   ovascii->tab = vascii->tab;
785ba5a0b41SBarry Smith   ovascii->closefile = PETSC_FALSE;
7865c6c1daeSBarry Smith 
7875c6c1daeSBarry Smith   vascii->sviewer = *outviewer;
7885c6c1daeSBarry Smith   (*outviewer)->format  = viewer->format;
7895c6c1daeSBarry Smith   ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
7903f08860eSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
7915c6c1daeSBarry Smith   PetscFunctionReturn(0);
7925c6c1daeSBarry Smith }
7935c6c1daeSBarry Smith 
7943f08860eSBarry Smith PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
7955c6c1daeSBarry Smith {
7965c6c1daeSBarry Smith   PetscErrorCode    ierr;
7975c6c1daeSBarry Smith   PetscViewer_ASCII *ascii  = (PetscViewer_ASCII*)viewer->data;
7985c6c1daeSBarry Smith 
7995c6c1daeSBarry Smith   PetscFunctionBegin;
800*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!ascii->sviewer,PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
801*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(ascii->sviewer != *outviewer,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
8025c6c1daeSBarry Smith 
8039530cbd7SBarry Smith   ierr = PetscViewerASCIIPopSynchronized(*outviewer);CHKERRQ(ierr);
804e5afcf28SBarry Smith   ascii->sviewer             = NULL;
8055c6c1daeSBarry Smith   (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
8065c6c1daeSBarry Smith   ierr                       = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
807e5afcf28SBarry Smith   ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
8085c6c1daeSBarry Smith   PetscFunctionReturn(0);
8095c6c1daeSBarry Smith }
8105c6c1daeSBarry Smith 
8112bf49c77SBarry Smith PetscErrorCode  PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
8122bf49c77SBarry Smith {
8132bf49c77SBarry Smith   PetscErrorCode    ierr;
8142bf49c77SBarry Smith   PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
8152bf49c77SBarry Smith 
8162bf49c77SBarry Smith   PetscFunctionBegin;
8172bf49c77SBarry Smith   if (ascii->filename) {
8182bf49c77SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
8192bf49c77SBarry Smith   }
8202bf49c77SBarry Smith   PetscFunctionReturn(0);
8212bf49c77SBarry Smith }
8222bf49c77SBarry Smith 
8238556b5ebSBarry Smith /*MC
8248556b5ebSBarry Smith    PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
8258556b5ebSBarry Smith 
8268556b5ebSBarry Smith .seealso:  PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
8278556b5ebSBarry Smith            PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
8288556b5ebSBarry Smith            PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
8298556b5ebSBarry Smith 
8301b266c99SBarry Smith   Level: beginner
8311b266c99SBarry Smith 
8328556b5ebSBarry Smith M*/
8338cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
8345c6c1daeSBarry Smith {
8355c6c1daeSBarry Smith   PetscViewer_ASCII *vascii;
8365c6c1daeSBarry Smith   PetscErrorCode    ierr;
8375c6c1daeSBarry Smith 
8385c6c1daeSBarry Smith   PetscFunctionBegin;
839b00a9115SJed Brown   ierr         = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
8405c6c1daeSBarry Smith   viewer->data = (void*)vascii;
8415c6c1daeSBarry Smith 
8425c6c1daeSBarry Smith   viewer->ops->destroy          = PetscViewerDestroy_ASCII;
8435c6c1daeSBarry Smith   viewer->ops->flush            = PetscViewerFlush_ASCII;
844559f443fSBarry Smith   viewer->ops->getsubviewer     = PetscViewerGetSubViewer_ASCII;
845559f443fSBarry Smith   viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
8462bf49c77SBarry Smith   viewer->ops->view             = PetscViewerView_ASCII;
8471d641e7bSMichael Lange   viewer->ops->read             = PetscViewerASCIIRead;
8485c6c1daeSBarry Smith 
8495c6c1daeSBarry Smith   /* defaults to stdout unless set with PetscViewerFileSetName() */
8505c6c1daeSBarry Smith   vascii->fd        = PETSC_STDOUT;
8515c6c1daeSBarry Smith   vascii->mode      = FILE_MODE_WRITE;
85202c9f0b5SLisandro Dalcin   vascii->bviewer   = NULL;
85302c9f0b5SLisandro Dalcin   vascii->subviewer = NULL;
85402c9f0b5SLisandro Dalcin   vascii->sviewer   = NULL;
8555c6c1daeSBarry Smith   vascii->tab       = 0;
8565c6c1daeSBarry Smith   vascii->tab_store = 0;
85702c9f0b5SLisandro Dalcin   vascii->filename  = NULL;
8585c6c1daeSBarry Smith   vascii->closefile = PETSC_TRUE;
8595c6c1daeSBarry Smith 
860bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
861bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
862bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
863bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
8645c6c1daeSBarry Smith   PetscFunctionReturn(0);
8655c6c1daeSBarry Smith }
8665c6c1daeSBarry Smith 
8675c6c1daeSBarry Smith /*@C
8685c6c1daeSBarry Smith     PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
8695c6c1daeSBarry Smith     several processors.  Output of the first processor is followed by that of the
8705c6c1daeSBarry Smith     second, etc.
8715c6c1daeSBarry Smith 
8725c6c1daeSBarry Smith     Not Collective, must call collective PetscViewerFlush() to get the results out
8735c6c1daeSBarry Smith 
8745c6c1daeSBarry Smith     Input Parameters:
8755c6c1daeSBarry Smith +   viewer - the ASCII PetscViewer
8765c6c1daeSBarry Smith -   format - the usual printf() format string
8775c6c1daeSBarry Smith 
8785c6c1daeSBarry Smith     Level: intermediate
8795c6c1daeSBarry Smith 
88095452b02SPatrick Sanan     Notes:
881e6abc3ddSVáclav Hapla     You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
882e6abc3ddSVáclav Hapla     Then you can do multiple independent calls to this routine.
883e6abc3ddSVáclav Hapla     The actual synchronized print is then done using PetscViewerFlush().
884e6abc3ddSVáclav Hapla     PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
885e6abc3ddSVáclav Hapla     to conclude the "synchronized session".
886e6abc3ddSVáclav Hapla     So the typical calling sequence looks like
887e6abc3ddSVáclav Hapla $ PetscViewerASCIIPushSynchronized(viewer);
888e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
889e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
890e6abc3ddSVáclav Hapla $ ...
891e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
892e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
893e6abc3ddSVáclav Hapla $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
894e6abc3ddSVáclav Hapla $ ...
895e6abc3ddSVáclav Hapla $ PetscViewerFlush(viewer);
896e6abc3ddSVáclav Hapla $ PetscViewerASCIIPopSynchronized(viewer);
8975c6c1daeSBarry Smith 
8985c6c1daeSBarry Smith     Fortran Note:
8995c6c1daeSBarry Smith       Can only print a single character* string
9005c6c1daeSBarry Smith 
901e6abc3ddSVáclav Hapla .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
902e6abc3ddSVáclav Hapla           PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
903e6abc3ddSVáclav Hapla           PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
9045c6c1daeSBarry Smith @*/
9055c6c1daeSBarry Smith PetscErrorCode  PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
9065c6c1daeSBarry Smith {
9075c6c1daeSBarry Smith   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
9085c6c1daeSBarry Smith   PetscErrorCode    ierr;
9093f08860eSBarry Smith   PetscMPIInt       rank;
9105c6c1daeSBarry Smith   PetscInt          tab = vascii->tab;
9115c6c1daeSBarry Smith   MPI_Comm          comm;
9125c6c1daeSBarry Smith   FILE              *fp;
913559f443fSBarry Smith   PetscBool         iascii,hasbviewer = PETSC_FALSE;
9145c6c1daeSBarry Smith   int               err;
9155c6c1daeSBarry Smith 
9165c6c1daeSBarry Smith   PetscFunctionBegin;
9175c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
9185c6c1daeSBarry Smith   PetscValidCharPointer(format,2);
9195c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
920*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!iascii,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
921*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!vascii->allowsynchronized,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
9225c6c1daeSBarry Smith 
923ce94432eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
924ffc4695bSBarry Smith   ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
9255c6c1daeSBarry Smith 
926559f443fSBarry Smith   if (vascii->bviewer) {
927559f443fSBarry Smith     hasbviewer = PETSC_TRUE;
928dd400576SPatrick Sanan     if (rank == 0) {
929559f443fSBarry Smith       vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
930559f443fSBarry Smith       ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
931ffc4695bSBarry Smith       ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr);
932559f443fSBarry Smith     }
933559f443fSBarry Smith   }
9343f08860eSBarry Smith 
935559f443fSBarry Smith   fp   = vascii->fd;
936559f443fSBarry Smith 
937dd400576SPatrick Sanan   if (rank == 0 && !hasbviewer) {   /* First processor prints immediately to fp */
9385c6c1daeSBarry Smith     va_list Argp;
939559f443fSBarry Smith     /* flush my own messages that I may have queued up */
940559f443fSBarry Smith     PrintfQueue next = vascii->petsc_printfqueuebase,previous;
941559f443fSBarry Smith     PetscInt    i;
942559f443fSBarry Smith     for (i=0; i<vascii->petsc_printfqueuelength; i++) {
943559f443fSBarry Smith       ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
944559f443fSBarry Smith       previous = next;
945559f443fSBarry Smith       next     = next->next;
946559f443fSBarry Smith       ierr     = PetscFree(previous->string);CHKERRQ(ierr);
947559f443fSBarry Smith       ierr     = PetscFree(previous);CHKERRQ(ierr);
948559f443fSBarry Smith     }
94902c9f0b5SLisandro Dalcin     vascii->petsc_printfqueue       = NULL;
950559f443fSBarry Smith     vascii->petsc_printfqueuelength = 0;
9515c6c1daeSBarry Smith 
952a297a907SKarl Rupp     while (tab--) {
953a297a907SKarl Rupp       ierr = PetscFPrintf(PETSC_COMM_SELF,fp,"  ");CHKERRQ(ierr);
954a297a907SKarl Rupp     }
9555c6c1daeSBarry Smith 
9565c6c1daeSBarry Smith     va_start(Argp,format);
9575c6c1daeSBarry Smith     ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
9585c6c1daeSBarry Smith     err  = fflush(fp);
959*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9605c6c1daeSBarry Smith     if (petsc_history) {
9615c6c1daeSBarry Smith       va_start(Argp,format);
9625c6c1daeSBarry Smith       ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
9635c6c1daeSBarry Smith       err  = fflush(petsc_history);
964*2c71b3e2SJacob Faibussowitsch       PetscCheckFalse(err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
9655c6c1daeSBarry Smith     }
9665c6c1daeSBarry Smith     va_end(Argp);
967559f443fSBarry Smith   } else { /* other processors add to queue */
9685c6c1daeSBarry Smith     char        *string;
9695c6c1daeSBarry Smith     va_list     Argp;
9705c6c1daeSBarry Smith     size_t      fullLength;
9715c6c1daeSBarry Smith     PrintfQueue next;
9725c6c1daeSBarry Smith 
973b00a9115SJed Brown     ierr = PetscNew(&next);CHKERRQ(ierr);
974559f443fSBarry Smith     if (vascii->petsc_printfqueue) {
975559f443fSBarry Smith       vascii->petsc_printfqueue->next = next;
976559f443fSBarry Smith       vascii->petsc_printfqueue       = next;
977a297a907SKarl Rupp     } else {
978559f443fSBarry Smith       vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
979a297a907SKarl Rupp     }
980559f443fSBarry Smith     vascii->petsc_printfqueuelength++;
9815c6c1daeSBarry Smith     next->size = QUEUESTRINGSIZE;
982580bdb30SBarry Smith     ierr       = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
9835c6c1daeSBarry Smith     string     = next->string;
9845c6c1daeSBarry Smith     tab       *= 2;
985a297a907SKarl Rupp     while (tab--) {
986a297a907SKarl Rupp       *string++ = ' ';
987a297a907SKarl Rupp     }
9885c6c1daeSBarry Smith     va_start(Argp,format);
98922d28d08SBarry Smith     ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
9905c6c1daeSBarry Smith     va_end(Argp);
991cb500232SBarry Smith     if (fullLength > (size_t) (next->size-2*vascii->tab)) {
99214416c0eSBarry Smith       ierr       = PetscFree(next->string);CHKERRQ(ierr);
99314416c0eSBarry Smith       next->size = fullLength + 2*vascii->tab;
994580bdb30SBarry Smith       ierr       = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
99514416c0eSBarry Smith       string     = next->string;
99614416c0eSBarry Smith       tab        = 2*vascii->tab;
99714416c0eSBarry Smith       while (tab--) {
99814416c0eSBarry Smith         *string++ = ' ';
99914416c0eSBarry Smith       }
100014416c0eSBarry Smith       va_start(Argp,format);
100114416c0eSBarry Smith       ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr);
100214416c0eSBarry Smith       va_end(Argp);
100314416c0eSBarry Smith     }
10045c6c1daeSBarry Smith   }
10055c6c1daeSBarry Smith   PetscFunctionReturn(0);
10065c6c1daeSBarry Smith }
10075c6c1daeSBarry Smith 
10082655f987SMichael Lange /*@C
1009f8859db6SBarry Smith    PetscViewerASCIIRead - Reads from a ASCII file
10102655f987SMichael Lange 
1011f8859db6SBarry Smith    Only process 0 in the PetscViewer may call this
10122655f987SMichael Lange 
10132655f987SMichael Lange    Input Parameters:
10142655f987SMichael Lange +  viewer - the ascii viewer
10152655f987SMichael Lange .  data - location to write the data
1016060da220SMatthew G. Knepley .  num - number of items of data to read
10172655f987SMichael Lange -  datatype - type of data to read
10182655f987SMichael Lange 
1019f8e4bde8SMatthew G. Knepley    Output Parameters:
1020060da220SMatthew G. Knepley .  count - number of items of data actually read, or NULL
1021f8e4bde8SMatthew G. Knepley 
10222655f987SMichael Lange    Level: beginner
10232655f987SMichael Lange 
1024f8859db6SBarry Smith .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
10252655f987SMichael Lange           VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
102605119932SBarry Smith           PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
10272655f987SMichael Lange @*/
1028060da220SMatthew G. Knepley PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
10292655f987SMichael Lange {
10302655f987SMichael Lange   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
10312655f987SMichael Lange   FILE              *fd = vascii->fd;
10322655f987SMichael Lange   PetscInt           i;
10333b7fe8c3SMatthew G. Knepley   int                ret = 0;
1034f8859db6SBarry Smith   PetscMPIInt        rank;
1035f8859db6SBarry Smith   PetscErrorCode     ierr;
10362655f987SMichael Lange 
10372655f987SMichael Lange   PetscFunctionBegin;
10382655f987SMichael Lange   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1039ffc4695bSBarry Smith   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRMPI(ierr);
1040*2c71b3e2SJacob Faibussowitsch   PetscCheckFalse(rank,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1041060da220SMatthew G. Knepley   for (i=0; i<num; i++) {
1042f8e4bde8SMatthew G. Knepley     if (dtype == PETSC_CHAR)         ret = fscanf(fd, "%c",  &(((char*)data)[i]));
1043f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_STRING)  ret = fscanf(fd, "%s",  &(((char*)data)[i]));
1044a05e1a72SSatish Balay     else if (dtype == PETSC_INT)     ret = fscanf(fd, "%" PetscInt_FMT,  &(((PetscInt*)data)[i]));
1045f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_ENUM)    ret = fscanf(fd, "%d",  &(((int*)data)[i]));
10469e3e4c22SLisandro Dalcin     else if (dtype == PETSC_INT64)   ret = fscanf(fd, "%" PetscInt64_FMT,  &(((PetscInt64*)data)[i]));
1047972064b6SLisandro Dalcin     else if (dtype == PETSC_LONG)    ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1048f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_FLOAT)   ret = fscanf(fd, "%f",  &(((float*)data)[i]));
1049f8e4bde8SMatthew G. Knepley     else if (dtype == PETSC_DOUBLE)  ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1050a6e181c6SToby Isaac #if defined(PETSC_USE_REAL___FLOAT128)
1051fba955ccSBarry Smith     else if (dtype == PETSC___FLOAT128) {
1052fba955ccSBarry Smith       double tmp;
1053fba955ccSBarry Smith       ret = fscanf(fd, "%lg", &tmp);
1054a6e181c6SToby Isaac       ((__float128*)data)[i] = tmp;
1055a6e181c6SToby Isaac     }
1056fba955ccSBarry Smith #endif
105798921bdaSJacob Faibussowitsch     else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1058*2c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!ret,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1059f8e4bde8SMatthew G. Knepley     else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
10602655f987SMichael Lange   }
1061060da220SMatthew G. Knepley   if (count) *count = i;
1062*2c71b3e2SJacob Faibussowitsch   else PetscCheckFalse(ret < 0,PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %" PetscInt_FMT " < %" PetscInt_FMT " items", i, num);
10632655f987SMichael Lange   PetscFunctionReturn(0);
10642655f987SMichael Lange }
1065