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