1
2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/
3
4 #define QUEUESTRINGSIZE 8192
5
PetscViewerFileClose_ASCII(PetscViewer viewer)6 static PetscErrorCode PetscViewerFileClose_ASCII(PetscViewer viewer)
7 {
8 PetscErrorCode ierr;
9 PetscMPIInt rank;
10 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
11 int err;
12
13 PetscFunctionBegin;
14 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
15 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
16 if (!rank && vascii->fd != stderr && vascii->fd != PETSC_STDOUT) {
17 if (vascii->fd && vascii->closefile) {
18 err = fclose(vascii->fd);
19 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
20 }
21 if (vascii->storecompressed) {
22 char par[PETSC_MAX_PATH_LEN],buf[PETSC_MAX_PATH_LEN];
23 FILE *fp;
24 ierr = PetscStrncpy(par,"gzip ",sizeof(par));CHKERRQ(ierr);
25 ierr = PetscStrlcat(par,vascii->filename,sizeof(par));CHKERRQ(ierr);
26 #if defined(PETSC_HAVE_POPEN)
27 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,par,"r",&fp);CHKERRQ(ierr);
28 if (fgets(buf,1024,fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from compression command %s\n%s",par,buf);
29 ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr);
30 #else
31 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
32 #endif
33 }
34 }
35 ierr = PetscFree(vascii->filename);CHKERRQ(ierr);
36 PetscFunctionReturn(0);
37 }
38
39 /* ----------------------------------------------------------------------*/
PetscViewerDestroy_ASCII(PetscViewer viewer)40 PetscErrorCode PetscViewerDestroy_ASCII(PetscViewer viewer)
41 {
42 PetscErrorCode ierr;
43 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
44 PetscViewerLink *vlink;
45 PetscBool flg;
46
47 PetscFunctionBegin;
48 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
49 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
50 ierr = PetscFree(vascii);CHKERRQ(ierr);
51
52 /* remove the viewer from the list in the MPI Communicator */
53 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
54 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr);
55 }
56
57 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr);
58 if (flg) {
59 if (vlink && vlink->viewer == viewer) {
60 if (vlink->next) {
61 ierr = MPI_Comm_set_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval,vlink->next);CHKERRQ(ierr);
62 } else {
63 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_keyval);CHKERRQ(ierr);
64 }
65 ierr = PetscFree(vlink);CHKERRQ(ierr);
66 } else {
67 while (vlink && vlink->next) {
68 if (vlink->next->viewer == viewer) {
69 PetscViewerLink *nv = vlink->next;
70 vlink->next = vlink->next->next;
71 ierr = PetscFree(nv);CHKERRQ(ierr);
72 }
73 vlink = vlink->next;
74 }
75 }
76 }
77
78 if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) {
79 PetscViewer aviewer;
80 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
81 if (flg && aviewer == viewer) {
82 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stdout_keyval);CHKERRQ(ierr);
83 }
84 }
85 if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) {
86 PetscViewer aviewer;
87 ierr = MPI_Comm_get_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval,(void**)&aviewer,(PetscMPIInt*)&flg);CHKERRQ(ierr);
88 if (flg && aviewer == viewer) {
89 ierr = MPI_Comm_delete_attr(PetscObjectComm((PetscObject)viewer),Petsc_Viewer_Stderr_keyval);CHKERRQ(ierr);
90 }
91 }
92 PetscFunctionReturn(0);
93 }
94
PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)95 PetscErrorCode PetscViewerDestroy_ASCII_SubViewer(PetscViewer viewer)
96 {
97 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
98 PetscErrorCode ierr;
99
100 PetscFunctionBegin;
101 ierr = PetscViewerRestoreSubViewer(vascii->bviewer,0,&viewer);CHKERRQ(ierr);
102 PetscFunctionReturn(0);
103 }
104
PetscViewerFlush_ASCII(PetscViewer viewer)105 PetscErrorCode PetscViewerFlush_ASCII(PetscViewer viewer)
106 {
107 PetscErrorCode ierr;
108 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
109 int err;
110 MPI_Comm comm;
111 PetscMPIInt rank,size;
112 FILE *fd = vascii->fd;
113
114 PetscFunctionBegin;
115 if (vascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
116 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
117 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
118 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
119
120 if (!vascii->bviewer && !rank && (vascii->mode != FILE_MODE_READ)) {
121 err = fflush(vascii->fd);
122 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() call failed");
123 }
124
125 if (vascii->allowsynchronized) {
126 PetscMPIInt tag,i,j,n = 0,dummy = 0;
127 char *message;
128 MPI_Status status;
129
130 ierr = PetscCommDuplicate(comm,&comm,&tag);CHKERRQ(ierr);
131
132 /* First processor waits for messages from all other processors */
133 if (!rank) {
134 /* flush my own messages that I may have queued up */
135 PrintfQueue next = vascii->petsc_printfqueuebase,previous;
136 for (i=0; i<vascii->petsc_printfqueuelength; i++) {
137 if (!vascii->bviewer) {
138 ierr = PetscFPrintf(comm,fd,"%s",next->string);CHKERRQ(ierr);
139 } else {
140 ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",next->string);CHKERRQ(ierr);
141 }
142 previous = next;
143 next = next->next;
144 ierr = PetscFree(previous->string);CHKERRQ(ierr);
145 ierr = PetscFree(previous);CHKERRQ(ierr);
146 }
147 vascii->petsc_printfqueue = NULL;
148 vascii->petsc_printfqueuelength = 0;
149 for (i=1; i<size; i++) {
150 /* to prevent a flood of messages to process zero, request each message separately */
151 ierr = MPI_Send(&dummy,1,MPI_INT,i,tag,comm);CHKERRQ(ierr);
152 ierr = MPI_Recv(&n,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
153 for (j=0; j<n; j++) {
154 PetscMPIInt size = 0;
155
156 ierr = MPI_Recv(&size,1,MPI_INT,i,tag,comm,&status);CHKERRQ(ierr);
157 ierr = PetscMalloc1(size, &message);CHKERRQ(ierr);
158 ierr = MPI_Recv(message,size,MPI_CHAR,i,tag,comm,&status);CHKERRQ(ierr);
159 if (!vascii->bviewer) {
160 ierr = PetscFPrintf(comm,fd,"%s",message);CHKERRQ(ierr);
161 } else {
162 ierr = PetscViewerASCIISynchronizedPrintf(vascii->bviewer,"%s",message);CHKERRQ(ierr);
163 }
164 ierr = PetscFree(message);CHKERRQ(ierr);
165 }
166 }
167 } else { /* other processors send queue to processor 0 */
168 PrintfQueue next = vascii->petsc_printfqueuebase,previous;
169
170 ierr = MPI_Recv(&dummy,1,MPI_INT,0,tag,comm,&status);CHKERRQ(ierr);
171 ierr = MPI_Send(&vascii->petsc_printfqueuelength,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
172 for (i=0; i<vascii->petsc_printfqueuelength; i++) {
173 ierr = MPI_Send(&next->size,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
174 ierr = MPI_Send(next->string,next->size,MPI_CHAR,0,tag,comm);CHKERRQ(ierr);
175 previous = next;
176 next = next->next;
177 ierr = PetscFree(previous->string);CHKERRQ(ierr);
178 ierr = PetscFree(previous);CHKERRQ(ierr);
179 }
180 vascii->petsc_printfqueue = NULL;
181 vascii->petsc_printfqueuelength = 0;
182 }
183 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr);
184 }
185 PetscFunctionReturn(0);
186 }
187
188 /*@C
189 PetscViewerASCIIGetPointer - Extracts the file pointer from an ASCII PetscViewer.
190
191 Not Collective, depending on the viewer the value may be meaningless except for process 0 of the viewer
192
193 Input Parameter:
194 . viewer - PetscViewer context, obtained from PetscViewerASCIIOpen()
195
196 Output Parameter:
197 . fd - file pointer
198
199 Notes: for the standard PETSCVIEWERASCII the value is valid only on process 0 of the viewer
200
201 Level: intermediate
202
203 Fortran Note:
204 This routine is not supported in Fortran.
205
206
207 .seealso: PetscViewerASCIIOpen(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerCreate(), PetscViewerASCIIPrintf(),
208 PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush()
209 @*/
PetscViewerASCIIGetPointer(PetscViewer viewer,FILE ** fd)210 PetscErrorCode PetscViewerASCIIGetPointer(PetscViewer viewer,FILE **fd)
211 {
212 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
213
214 PetscFunctionBegin;
215 *fd = vascii->fd;
216 PetscFunctionReturn(0);
217 }
218
PetscViewerFileGetMode_ASCII(PetscViewer viewer,PetscFileMode * mode)219 PetscErrorCode PetscViewerFileGetMode_ASCII(PetscViewer viewer, PetscFileMode *mode)
220 {
221 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
222
223 PetscFunctionBegin;
224 *mode = vascii->mode;
225 PetscFunctionReturn(0);
226 }
227
PetscViewerFileSetMode_ASCII(PetscViewer viewer,PetscFileMode mode)228 PetscErrorCode PetscViewerFileSetMode_ASCII(PetscViewer viewer, PetscFileMode mode)
229 {
230 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
231
232 PetscFunctionBegin;
233 vascii->mode = mode;
234 PetscFunctionReturn(0);
235 }
236
237 /*
238 If petsc_history is on, then all Petsc*Printf() results are saved
239 if the appropriate (usually .petschistory) file.
240 */
241 PETSC_INTERN FILE *petsc_history;
242
243 /*@
244 PetscViewerASCIISetTab - Causes PetscViewer to tab in a number of times
245
246 Not Collective, but only first processor in set has any effect
247
248 Input Parameters:
249 + viewer - obtained with PetscViewerASCIIOpen()
250 - tabs - number of tabs
251
252 Level: developer
253
254 Fortran Note:
255 This routine is not supported in Fortran.
256
257
258 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIGetTab(),
259 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
260 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
261 @*/
PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)262 PetscErrorCode PetscViewerASCIISetTab(PetscViewer viewer,PetscInt tabs)
263 {
264 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
265 PetscBool iascii;
266 PetscErrorCode ierr;
267
268 PetscFunctionBegin;
269 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
270 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
271 if (iascii) ascii->tab = tabs;
272 PetscFunctionReturn(0);
273 }
274
275 /*@
276 PetscViewerASCIIGetTab - Return the number of tabs used by PetscViewer.
277
278 Not Collective, meaningful on first processor only.
279
280 Input Parameters:
281 . viewer - obtained with PetscViewerASCIIOpen()
282
283 Output Parameters:
284 . tabs - number of tabs
285
286 Level: developer
287
288 Fortran Note:
289 This routine is not supported in Fortran.
290
291
292 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIISetTab(),
293 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
294 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
295 @*/
PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt * tabs)296 PetscErrorCode PetscViewerASCIIGetTab(PetscViewer viewer,PetscInt *tabs)
297 {
298 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
299 PetscBool iascii;
300 PetscErrorCode ierr;
301
302 PetscFunctionBegin;
303 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
304 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
305 if (iascii && tabs) *tabs = ascii->tab;
306 PetscFunctionReturn(0);
307 }
308
309 /*@
310 PetscViewerASCIIAddTab - Add to the number of times an ASCII viewer tabs before printing
311
312 Not Collective, but only first processor in set has any effect
313
314 Input Parameters:
315 + viewer - obtained with PetscViewerASCIIOpen()
316 - tabs - number of tabs
317
318 Level: developer
319
320 Fortran Note:
321 This routine is not supported in Fortran.
322
323
324 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
325 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
326 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
327 @*/
PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)328 PetscErrorCode PetscViewerASCIIAddTab(PetscViewer viewer,PetscInt tabs)
329 {
330 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
331 PetscBool iascii;
332 PetscErrorCode ierr;
333
334 PetscFunctionBegin;
335 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
336 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
337 if (iascii) ascii->tab += tabs;
338 PetscFunctionReturn(0);
339 }
340
341 /*@
342 PetscViewerASCIISubtractTab - Subtracts from the number of times an ASCII viewer tabs before printing
343
344 Not Collective, but only first processor in set has any effect
345
346 Input Parameters:
347 + viewer - obtained with PetscViewerASCIIOpen()
348 - tabs - number of tabs
349
350 Level: developer
351
352 Fortran Note:
353 This routine is not supported in Fortran.
354
355
356 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
357 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
358 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushTab()
359 @*/
PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)360 PetscErrorCode PetscViewerASCIISubtractTab(PetscViewer viewer,PetscInt tabs)
361 {
362 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
363 PetscBool iascii;
364 PetscErrorCode ierr;
365
366 PetscFunctionBegin;
367 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
368 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
369 if (iascii) ascii->tab -= tabs;
370 PetscFunctionReturn(0);
371 }
372
373 /*@C
374 PetscViewerASCIIPushSynchronized - Allows calls to PetscViewerASCIISynchronizedPrintf() for this viewer
375
376 Collective on PetscViewer
377
378 Input Parameters:
379 . viewer - obtained with PetscViewerASCIIOpen()
380
381 Level: intermediate
382
383 Notes:
384 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
385
386
387 .seealso: PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
388 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
389 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
390 @*/
PetscViewerASCIIPushSynchronized(PetscViewer viewer)391 PetscErrorCode PetscViewerASCIIPushSynchronized(PetscViewer viewer)
392 {
393 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
394 PetscBool iascii;
395 PetscErrorCode ierr;
396
397 PetscFunctionBegin;
398 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
399 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
400 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
401 if (iascii) ascii->allowsynchronized++;
402 PetscFunctionReturn(0);
403 }
404
405 /*@C
406 PetscViewerASCIIPopSynchronized - Undoes most recent PetscViewerASCIIPushSynchronized() for this viewer
407
408 Collective on PetscViewer
409
410 Input Parameters:
411 . viewer - obtained with PetscViewerASCIIOpen()
412
413 Level: intermediate
414
415 Notes:
416 See documentation of PetscViewerASCIISynchronizedPrintf() for more details how the synchronized output should be done properly.
417
418
419 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerASCIISynchronizedPrintf(), PetscViewerFlush(),
420 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
421 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
422 @*/
PetscViewerASCIIPopSynchronized(PetscViewer viewer)423 PetscErrorCode PetscViewerASCIIPopSynchronized(PetscViewer viewer)
424 {
425 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
426 PetscBool iascii;
427 PetscErrorCode ierr;
428
429 PetscFunctionBegin;
430 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
431 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
432 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
433 if (iascii) {
434 ascii->allowsynchronized--;
435 if (ascii->allowsynchronized < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Called more times than PetscViewerASCIIPushSynchronized()");
436 }
437 PetscFunctionReturn(0);
438 }
439
440 /*@C
441 PetscViewerASCIIPushTab - Adds one more tab to the amount that PetscViewerASCIIPrintf()
442 lines are tabbed.
443
444 Not Collective, but only first processor in set has any effect
445
446 Input Parameters:
447 . viewer - obtained with PetscViewerASCIIOpen()
448
449 Level: developer
450
451 Fortran Note:
452 This routine is not supported in Fortran.
453
454
455 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
456 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
457 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
458 @*/
PetscViewerASCIIPushTab(PetscViewer viewer)459 PetscErrorCode PetscViewerASCIIPushTab(PetscViewer viewer)
460 {
461 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
462 PetscBool iascii;
463 PetscErrorCode ierr;
464
465 PetscFunctionBegin;
466 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
467 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
468 if (iascii) ascii->tab++;
469 PetscFunctionReturn(0);
470 }
471
472 /*@C
473 PetscViewerASCIIPopTab - Removes one tab from the amount that PetscViewerASCIIPrintf()
474 lines are tabbed.
475
476 Not Collective, but only first processor in set has any effect
477
478 Input Parameters:
479 . viewer - obtained with PetscViewerASCIIOpen()
480
481 Level: developer
482
483 Fortran Note:
484 This routine is not supported in Fortran.
485
486
487 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
488 PetscViewerASCIIPushTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIOpen(),
489 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
490 @*/
PetscViewerASCIIPopTab(PetscViewer viewer)491 PetscErrorCode PetscViewerASCIIPopTab(PetscViewer viewer)
492 {
493 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
494 PetscErrorCode ierr;
495 PetscBool iascii;
496
497 PetscFunctionBegin;
498 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
499 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
500 if (iascii) {
501 if (ascii->tab <= 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More tabs popped than pushed");
502 ascii->tab--;
503 }
504 PetscFunctionReturn(0);
505 }
506
507 /*@
508 PetscViewerASCIIUseTabs - Turns on or off the use of tabs with the ASCII PetscViewer
509
510 Not Collective, but only first processor in set has any effect
511
512 Input Parameters:
513 + viewer - obtained with PetscViewerASCIIOpen()
514 - flg - PETSC_TRUE or PETSC_FALSE
515
516 Level: developer
517
518 Fortran Note:
519 This routine is not supported in Fortran.
520
521
522 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(),
523 PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(), PetscViewerASCIIPushTab(), PetscViewerASCIIOpen(),
524 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer()
525 @*/
PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)526 PetscErrorCode PetscViewerASCIIUseTabs(PetscViewer viewer,PetscBool flg)
527 {
528 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
529 PetscBool iascii;
530 PetscErrorCode ierr;
531
532 PetscFunctionBegin;
533 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
534 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
535 if (iascii) {
536 if (flg) ascii->tab = ascii->tab_store;
537 else {
538 ascii->tab_store = ascii->tab;
539 ascii->tab = 0;
540 }
541 }
542 PetscFunctionReturn(0);
543 }
544
545 /* ----------------------------------------------------------------------- */
546
547
548 /*@C
549 PetscViewerASCIIPrintf - Prints to a file, only from the first
550 processor in the PetscViewer
551
552 Not Collective, but only first processor in set has any effect
553
554 Input Parameters:
555 + viewer - obtained with PetscViewerASCIIOpen()
556 - format - the usual printf() format string
557
558 Level: developer
559
560 Fortran Note:
561 The call sequence is PetscViewerASCIIPrintf(PetscViewer, character(*), int ierr) from Fortran.
562 That is, you can only pass a single character string from Fortran.
563
564 .seealso: PetscPrintf(), PetscSynchronizedPrintf(), PetscViewerASCIIOpen(),
565 PetscViewerASCIIPushTab(), PetscViewerASCIIPopTab(), PetscViewerASCIISynchronizedPrintf(),
566 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType(), PetscViewerASCIIGetPointer(), PetscViewerASCIIPushSynchronized()
567 @*/
PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)568 PetscErrorCode PetscViewerASCIIPrintf(PetscViewer viewer,const char format[],...)
569 {
570 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
571 PetscMPIInt rank;
572 PetscInt tab,intab = ascii->tab;
573 PetscErrorCode ierr;
574 FILE *fd = ascii->fd;
575 PetscBool iascii;
576 int err;
577
578 PetscFunctionBegin;
579 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
580 if (ascii->sviewer) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_WRONGSTATE,"Cannot call with outstanding call to PetscViewerRestoreSubViewer()");
581 PetscValidCharPointer(format,2);
582 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
583 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
584 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
585 if (rank) PetscFunctionReturn(0);
586
587 if (ascii->bviewer) { /* pass string up to parent viewer */
588 char *string;
589 va_list Argp;
590 size_t fullLength;
591
592 ierr = PetscCalloc1(QUEUESTRINGSIZE, &string);CHKERRQ(ierr);
593 va_start(Argp,format);
594 ierr = PetscVSNPrintf(string,QUEUESTRINGSIZE,format,&fullLength,Argp);CHKERRQ(ierr);
595 va_end(Argp);
596 ierr = PetscViewerASCIISynchronizedPrintf(viewer,"%s",string);CHKERRQ(ierr);
597 ierr = PetscFree(string);CHKERRQ(ierr);
598 } else { /* write directly to file */
599 va_list Argp;
600 /* flush my own messages that I may have queued up */
601 PrintfQueue next = ascii->petsc_printfqueuebase,previous;
602 PetscInt i;
603 for (i=0; i<ascii->petsc_printfqueuelength; i++) {
604 ierr = PetscFPrintf(PETSC_COMM_SELF,fd,"%s",next->string);CHKERRQ(ierr);
605 previous = next;
606 next = next->next;
607 ierr = PetscFree(previous->string);CHKERRQ(ierr);
608 ierr = PetscFree(previous);CHKERRQ(ierr);
609 }
610 ascii->petsc_printfqueue = NULL;
611 ascii->petsc_printfqueuelength = 0;
612 tab = intab;
613 while (tab--) {
614 ierr = PetscFPrintf(PETSC_COMM_SELF,fd," ");CHKERRQ(ierr);
615 }
616
617 va_start(Argp,format);
618 ierr = (*PetscVFPrintf)(fd,format,Argp);CHKERRQ(ierr);
619 err = fflush(fd);
620 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
621 if (petsc_history) {
622 va_start(Argp,format);
623 tab = intab;
624 while (tab--) {
625 ierr = PetscFPrintf(PETSC_COMM_SELF,petsc_history," ");CHKERRQ(ierr);
626 }
627 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
628 err = fflush(petsc_history);
629 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
630 }
631 va_end(Argp);
632 }
633 PetscFunctionReturn(0);
634 }
635
636 /*@C
637 PetscViewerFileSetName - Sets the name of the file the PetscViewer uses.
638
639 Collective on PetscViewer
640
641 Input Parameters:
642 + viewer - the PetscViewer; either ASCII or binary
643 - name - the name of the file it should use
644
645 Level: advanced
646
647 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerDestroy(),
648 PetscViewerASCIIGetPointer(), PetscViewerASCIIPrintf(), PetscViewerASCIISynchronizedPrintf()
649
650 @*/
PetscViewerFileSetName(PetscViewer viewer,const char name[])651 PetscErrorCode PetscViewerFileSetName(PetscViewer viewer,const char name[])
652 {
653 PetscErrorCode ierr;
654 char filename[PETSC_MAX_PATH_LEN];
655
656 PetscFunctionBegin;
657 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
658 PetscValidCharPointer(name,2);
659 ierr = PetscStrreplace(PetscObjectComm((PetscObject)viewer),name,filename,sizeof(filename));CHKERRQ(ierr);
660 ierr = PetscTryMethod(viewer,"PetscViewerFileSetName_C",(PetscViewer,const char[]),(viewer,filename));CHKERRQ(ierr);
661 PetscFunctionReturn(0);
662 }
663
664 /*@C
665 PetscViewerFileGetName - Gets the name of the file the PetscViewer uses.
666
667 Not Collective
668
669 Input Parameter:
670 . viewer - the PetscViewer; either ASCII or binary
671
672 Output Parameter:
673 . name - the name of the file it is using
674
675 Level: advanced
676
677 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PetscViewerFileSetName()
678
679 @*/
PetscViewerFileGetName(PetscViewer viewer,const char ** name)680 PetscErrorCode PetscViewerFileGetName(PetscViewer viewer,const char **name)
681 {
682 PetscErrorCode ierr;
683
684 PetscFunctionBegin;
685 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
686 PetscValidPointer(name,2);
687 ierr = PetscUseMethod(viewer,"PetscViewerFileGetName_C",(PetscViewer,const char**),(viewer,name));CHKERRQ(ierr);
688 PetscFunctionReturn(0);
689 }
690
PetscViewerFileGetName_ASCII(PetscViewer viewer,const char ** name)691 PetscErrorCode PetscViewerFileGetName_ASCII(PetscViewer viewer,const char **name)
692 {
693 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
694
695 PetscFunctionBegin;
696 *name = vascii->filename;
697 PetscFunctionReturn(0);
698 }
699
PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])700 PetscErrorCode PetscViewerFileSetName_ASCII(PetscViewer viewer,const char name[])
701 {
702 PetscErrorCode ierr;
703 size_t len;
704 char fname[PETSC_MAX_PATH_LEN],*gz;
705 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
706 PetscBool isstderr,isstdout;
707 PetscMPIInt rank;
708
709 PetscFunctionBegin;
710 ierr = PetscViewerFileClose_ASCII(viewer);CHKERRQ(ierr);
711 if (!name) PetscFunctionReturn(0);
712 ierr = PetscStrallocpy(name,&vascii->filename);CHKERRQ(ierr);
713
714 /* Is this file to be compressed */
715 vascii->storecompressed = PETSC_FALSE;
716
717 ierr = PetscStrstr(vascii->filename,".gz",&gz);CHKERRQ(ierr);
718 if (gz) {
719 ierr = PetscStrlen(gz,&len);CHKERRQ(ierr);
720 if (len == 3) {
721 if (vascii->mode != FILE_MODE_WRITE) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Cannot open ASCII PetscViewer file that is compressed; uncompress it manually first");
722 *gz = 0;
723 vascii->storecompressed = PETSC_TRUE;
724 }
725 }
726 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
727 if (!rank) {
728 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr);
729 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr);
730 /* empty filename means stdout */
731 if (name[0] == 0) isstdout = PETSC_TRUE;
732 if (isstderr) vascii->fd = PETSC_STDERR;
733 else if (isstdout) vascii->fd = PETSC_STDOUT;
734 else {
735
736
737 ierr = PetscFixFilename(name,fname);CHKERRQ(ierr);
738 switch (vascii->mode) {
739 case FILE_MODE_READ:
740 vascii->fd = fopen(fname,"r");
741 break;
742 case FILE_MODE_WRITE:
743 vascii->fd = fopen(fname,"w");
744 break;
745 case FILE_MODE_APPEND:
746 vascii->fd = fopen(fname,"a");
747 break;
748 case FILE_MODE_UPDATE:
749 vascii->fd = fopen(fname,"r+");
750 if (!vascii->fd) vascii->fd = fopen(fname,"w+");
751 break;
752 case FILE_MODE_APPEND_UPDATE:
753 /* I really want a file which is opened at the end for updating,
754 not a+, which opens at the beginning, but makes writes at the end.
755 */
756 vascii->fd = fopen(fname,"r+");
757 if (!vascii->fd) vascii->fd = fopen(fname,"w+");
758 else {
759 ierr = fseek(vascii->fd, 0, SEEK_END);CHKERRQ(ierr);
760 }
761 break;
762 default:
763 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG, "Invalid file mode %d", vascii->mode);
764 }
765 if (!vascii->fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open PetscViewer file: %s",fname);
766 }
767 }
768 #if defined(PETSC_USE_LOG)
769 PetscLogObjectState((PetscObject)viewer,"File: %s",name);
770 #endif
771 PetscFunctionReturn(0);
772 }
773
PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer * outviewer)774 PetscErrorCode PetscViewerGetSubViewer_ASCII(PetscViewer viewer,MPI_Comm subcomm,PetscViewer *outviewer)
775 {
776 PetscMPIInt rank;
777 PetscErrorCode ierr;
778 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data,*ovascii;
779
780 PetscFunctionBegin;
781 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
782 if (vascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer already obtained from PetscViewer and not restored");
783 /*
784 The following line is a bug; but if it is removed the code won't work because it relies on this behavior. In particular
785 this line causes the synchronized flush to occur when the viewer is destroyed (since the count never gets to zero)
786 in some examples this displays information that otherwise would be lost
787 */
788 ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
789 ierr = PetscViewerCreate(subcomm,outviewer);CHKERRQ(ierr);
790 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERASCII);CHKERRQ(ierr);
791 ierr = PetscViewerASCIIPushSynchronized(*outviewer);CHKERRQ(ierr);
792 ovascii = (PetscViewer_ASCII*)(*outviewer)->data;
793 ovascii->fd = vascii->fd;
794 ovascii->tab = vascii->tab;
795 ovascii->closefile = PETSC_FALSE;
796
797 vascii->sviewer = *outviewer;
798
799 (*outviewer)->format = viewer->format;
800
801 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
802 ((PetscViewer_ASCII*)((*outviewer)->data))->bviewer = viewer;
803 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII_SubViewer;
804 PetscFunctionReturn(0);
805 }
806
PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)807 PetscErrorCode PetscViewerRestoreSubViewer_ASCII(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
808 {
809 PetscErrorCode ierr;
810 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)viewer->data;
811
812 PetscFunctionBegin;
813 if (!ascii->sviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"SubViewer never obtained from PetscViewer");
814 if (ascii->sviewer != *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"This PetscViewer did not generate this SubViewer");
815
816 ascii->sviewer = NULL;
817 (*outviewer)->ops->destroy = PetscViewerDestroy_ASCII;
818 ierr = PetscViewerDestroy(outviewer);CHKERRQ(ierr);
819 ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
820 PetscFunctionReturn(0);
821 }
822
PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)823 PetscErrorCode PetscViewerView_ASCII(PetscViewer v,PetscViewer viewer)
824 {
825 PetscErrorCode ierr;
826 PetscViewer_ASCII *ascii = (PetscViewer_ASCII*)v->data;
827
828 PetscFunctionBegin;
829 if (ascii->filename) {
830 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",ascii->filename);CHKERRQ(ierr);
831 }
832 PetscFunctionReturn(0);
833 }
834
835 /*MC
836 PETSCVIEWERASCII - A viewer that prints to stdout or an ASCII file
837
838
839 .seealso: PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD,PetscViewerCreate(), PetscViewerASCIIOpen(),
840 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERBINARY, PETSCVIEWERMATLAB,
841 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType()
842
843 Level: beginner
844
845 M*/
PetscViewerCreate_ASCII(PetscViewer viewer)846 PETSC_EXTERN PetscErrorCode PetscViewerCreate_ASCII(PetscViewer viewer)
847 {
848 PetscViewer_ASCII *vascii;
849 PetscErrorCode ierr;
850
851 PetscFunctionBegin;
852 ierr = PetscNewLog(viewer,&vascii);CHKERRQ(ierr);
853 viewer->data = (void*)vascii;
854
855 viewer->ops->destroy = PetscViewerDestroy_ASCII;
856 viewer->ops->flush = PetscViewerFlush_ASCII;
857 viewer->ops->getsubviewer = PetscViewerGetSubViewer_ASCII;
858 viewer->ops->restoresubviewer = PetscViewerRestoreSubViewer_ASCII;
859 viewer->ops->view = PetscViewerView_ASCII;
860 viewer->ops->read = PetscViewerASCIIRead;
861
862 /* defaults to stdout unless set with PetscViewerFileSetName() */
863 vascii->fd = PETSC_STDOUT;
864 vascii->mode = FILE_MODE_WRITE;
865 vascii->bviewer = NULL;
866 vascii->subviewer = NULL;
867 vascii->sviewer = NULL;
868 vascii->tab = 0;
869 vascii->tab_store = 0;
870 vascii->filename = NULL;
871 vascii->closefile = PETSC_TRUE;
872
873 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetName_C",PetscViewerFileSetName_ASCII);CHKERRQ(ierr);
874 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetName_C",PetscViewerFileGetName_ASCII);CHKERRQ(ierr);
875 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_ASCII);CHKERRQ(ierr);
876 ierr = PetscObjectComposeFunction((PetscObject)viewer,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_ASCII);CHKERRQ(ierr);
877 PetscFunctionReturn(0);
878 }
879
880 /*@C
881 PetscViewerASCIISynchronizedPrintf - Prints synchronized output to the specified file from
882 several processors. Output of the first processor is followed by that of the
883 second, etc.
884
885 Not Collective, must call collective PetscViewerFlush() to get the results out
886
887 Input Parameters:
888 + viewer - the ASCII PetscViewer
889 - format - the usual printf() format string
890
891 Level: intermediate
892
893 Notes:
894 You must have previously called PetscViewerASCIIPushSynchronized() to allow this routine to be called.
895 Then you can do multiple independent calls to this routine.
896 The actual synchronized print is then done using PetscViewerFlush().
897 PetscViewerASCIIPopSynchronized() should be then called if we are already done with the synchronized output
898 to conclude the "synchronized session".
899 So the typical calling sequence looks like
900 $ PetscViewerASCIIPushSynchronized(viewer);
901 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
902 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
903 $ ...
904 $ PetscViewerFlush(viewer);
905 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
906 $ PetscViewerASCIISynchronizedPrintf(viewer, ...);
907 $ ...
908 $ PetscViewerFlush(viewer);
909 $ PetscViewerASCIIPopSynchronized(viewer);
910
911 Fortran Note:
912 Can only print a single character* string
913
914 .seealso: PetscViewerASCIIPushSynchronized(), PetscViewerFlush(), PetscViewerASCIIPopSynchronized(),
915 PetscSynchronizedPrintf(), PetscViewerASCIIPrintf(), PetscViewerASCIIOpen(),
916 PetscViewerCreate(), PetscViewerDestroy(), PetscViewerSetType()
917 @*/
PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)918 PetscErrorCode PetscViewerASCIISynchronizedPrintf(PetscViewer viewer,const char format[],...)
919 {
920 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
921 PetscErrorCode ierr;
922 PetscMPIInt rank;
923 PetscInt tab = vascii->tab;
924 MPI_Comm comm;
925 FILE *fp;
926 PetscBool iascii,hasbviewer = PETSC_FALSE;
927 int err;
928
929 PetscFunctionBegin;
930 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
931 PetscValidCharPointer(format,2);
932 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
933 if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not ASCII PetscViewer");
934 if (!vascii->allowsynchronized) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"First call PetscViewerASCIIPushSynchronized() to allow this call");
935
936 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
937 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
938
939 if (vascii->bviewer) {
940 hasbviewer = PETSC_TRUE;
941 if (!rank) {
942 vascii = (PetscViewer_ASCII*)vascii->bviewer->data;
943 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
944 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
945 }
946 }
947
948 fp = vascii->fd;
949
950 if (!rank && !hasbviewer) { /* First processor prints immediately to fp */
951 va_list Argp;
952 /* flush my own messages that I may have queued up */
953 PrintfQueue next = vascii->petsc_printfqueuebase,previous;
954 PetscInt i;
955 for (i=0; i<vascii->petsc_printfqueuelength; i++) {
956 ierr = PetscFPrintf(comm,fp,"%s",next->string);CHKERRQ(ierr);
957 previous = next;
958 next = next->next;
959 ierr = PetscFree(previous->string);CHKERRQ(ierr);
960 ierr = PetscFree(previous);CHKERRQ(ierr);
961 }
962 vascii->petsc_printfqueue = NULL;
963 vascii->petsc_printfqueuelength = 0;
964
965 while (tab--) {
966 ierr = PetscFPrintf(PETSC_COMM_SELF,fp," ");CHKERRQ(ierr);
967 }
968
969 va_start(Argp,format);
970 ierr = (*PetscVFPrintf)(fp,format,Argp);CHKERRQ(ierr);
971 err = fflush(fp);
972 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
973 if (petsc_history) {
974 va_start(Argp,format);
975 ierr = (*PetscVFPrintf)(petsc_history,format,Argp);CHKERRQ(ierr);
976 err = fflush(petsc_history);
977 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on file");
978 }
979 va_end(Argp);
980 } else { /* other processors add to queue */
981 char *string;
982 va_list Argp;
983 size_t fullLength;
984 PrintfQueue next;
985
986 ierr = PetscNew(&next);CHKERRQ(ierr);
987 if (vascii->petsc_printfqueue) {
988 vascii->petsc_printfqueue->next = next;
989 vascii->petsc_printfqueue = next;
990 } else {
991 vascii->petsc_printfqueuebase = vascii->petsc_printfqueue = next;
992 }
993 vascii->petsc_printfqueuelength++;
994 next->size = QUEUESTRINGSIZE;
995 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
996 string = next->string;
997 tab *= 2;
998 while (tab--) {
999 *string++ = ' ';
1000 }
1001 va_start(Argp,format);
1002 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,&fullLength,Argp);CHKERRQ(ierr);
1003 va_end(Argp);
1004 if (fullLength > (size_t) (next->size-2*vascii->tab)) {
1005 ierr = PetscFree(next->string);CHKERRQ(ierr);
1006 next->size = fullLength + 2*vascii->tab;
1007 ierr = PetscCalloc1(next->size, &next->string);CHKERRQ(ierr);
1008 string = next->string;
1009 tab = 2*vascii->tab;
1010 while (tab--) {
1011 *string++ = ' ';
1012 }
1013 va_start(Argp,format);
1014 ierr = PetscVSNPrintf(string,next->size-2*vascii->tab,format,NULL,Argp);CHKERRQ(ierr);
1015 va_end(Argp);
1016 }
1017 }
1018 PetscFunctionReturn(0);
1019 }
1020
1021 /*@C
1022 PetscViewerASCIIRead - Reads from a ASCII file
1023
1024 Only process 0 in the PetscViewer may call this
1025
1026 Input Parameters:
1027 + viewer - the ascii viewer
1028 . data - location to write the data
1029 . num - number of items of data to read
1030 - datatype - type of data to read
1031
1032 Output Parameters:
1033 . count - number of items of data actually read, or NULL
1034
1035 Level: beginner
1036
1037 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerFileSetMode(), PetscViewerFileSetName()
1038 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1039 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1040 @*/
PetscViewerASCIIRead(PetscViewer viewer,void * data,PetscInt num,PetscInt * count,PetscDataType dtype)1041 PetscErrorCode PetscViewerASCIIRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
1042 {
1043 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;
1044 FILE *fd = vascii->fd;
1045 PetscInt i;
1046 int ret = 0;
1047 PetscMPIInt rank;
1048 PetscErrorCode ierr;
1049
1050 PetscFunctionBegin;
1051 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1052 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1053 if (rank) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,"Can only be called from process 0 in the PetscViewer");
1054 for (i=0; i<num; i++) {
1055 if (dtype == PETSC_CHAR) ret = fscanf(fd, "%c", &(((char*)data)[i]));
1056 else if (dtype == PETSC_STRING) ret = fscanf(fd, "%s", &(((char*)data)[i]));
1057 else if (dtype == PETSC_INT) ret = fscanf(fd, "%" PetscInt_FMT, &(((PetscInt*)data)[i]));
1058 else if (dtype == PETSC_ENUM) ret = fscanf(fd, "%d", &(((int*)data)[i]));
1059 else if (dtype == PETSC_INT64) ret = fscanf(fd, "%" PetscInt64_FMT, &(((PetscInt64*)data)[i]));
1060 else if (dtype == PETSC_LONG) ret = fscanf(fd, "%ld", &(((long*)data)[i]));
1061 else if (dtype == PETSC_FLOAT) ret = fscanf(fd, "%f", &(((float*)data)[i]));
1062 else if (dtype == PETSC_DOUBLE) ret = fscanf(fd, "%lg", &(((double*)data)[i]));
1063 #if defined(PETSC_USE_REAL___FLOAT128)
1064 else if (dtype == PETSC___FLOAT128) {
1065 double tmp;
1066 ret = fscanf(fd, "%lg", &tmp);
1067 ((__float128*)data)[i] = tmp;
1068 }
1069 #endif
1070 else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Data type %d not supported", (int) dtype);
1071 if (!ret) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Conversion error for data type %d", (int) dtype);
1072 else if (ret < 0) break; /* Proxy for EOF, need to check for it in configure */
1073 }
1074 if (count) *count = i;
1075 else if (ret < 0) SETERRQ2(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Insufficient data, read only %D < %D items", i, num);
1076 PetscFunctionReturn(0);
1077 }
1078