Actual source code: view.c
1: #include <petsc/private/viewerimpl.h>
2: #include <petscdraw.h>
4: PetscClassId PETSC_VIEWER_CLASSID;
6: static PetscBool PetscViewerPackageInitialized = PETSC_FALSE;
8: /*@C
9: PetscViewerFinalizePackage - This function destroys any global objects created in PETSc viewers. It is
10: called from `PetscFinalize()`.
12: Level: developer
14: .seealso: [](sec_viewers), `PetscViewer`, `PetscFinalize()`, `PetscViewerInitializePackage()`
15: @*/
16: PetscErrorCode PetscViewerFinalizePackage(void)
17: {
18: PetscFunctionBegin;
19: if (Petsc_Viewer_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_keyval));
20: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stdout_keyval));
21: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stderr_keyval));
22: if (Petsc_Viewer_Binary_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Binary_keyval));
23: if (Petsc_Viewer_Draw_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Draw_keyval));
24: #if defined(PETSC_HAVE_HDF5)
25: if (Petsc_Viewer_HDF5_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_HDF5_keyval));
26: #endif
27: #if defined(PETSC_USE_SOCKETVIEWER)
28: if (Petsc_Viewer_Socket_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Socket_keyval));
29: #endif
30: PetscCall(PetscFunctionListDestroy(&PetscViewerList));
31: PetscViewerPackageInitialized = PETSC_FALSE;
32: PetscViewerRegisterAllCalled = PETSC_FALSE;
33: PetscFunctionReturn(PETSC_SUCCESS);
34: }
36: /*@C
37: PetscViewerInitializePackage - This function initializes everything in the `PetscViewer` package.
39: Level: developer
41: .seealso: [](sec_viewers), `PetscViewer`, `PetscInitialize()`, `PetscViewerFinalizePackage()`
42: @*/
43: PetscErrorCode PetscViewerInitializePackage(void)
44: {
45: char logList[256];
46: PetscBool opt, pkg;
48: PetscFunctionBegin;
49: if (PetscViewerPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
50: PetscViewerPackageInitialized = PETSC_TRUE;
51: /* Register Classes */
52: PetscCall(PetscClassIdRegister("Viewer", &PETSC_VIEWER_CLASSID));
53: /* Register Constructors */
54: PetscCall(PetscViewerRegisterAll());
55: /* Process Info */
56: {
57: PetscClassId classids[1];
59: classids[0] = PETSC_VIEWER_CLASSID;
60: PetscCall(PetscInfoProcessClass("viewer", 1, classids));
61: }
62: /* Process summary exclusions */
63: PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
64: if (opt) {
65: PetscCall(PetscStrInList("viewer", logList, ',', &pkg));
66: if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_VIEWER_CLASSID));
67: }
68: #if defined(PETSC_HAVE_MATHEMATICA)
69: PetscCall(PetscViewerMathematicaInitializePackage());
70: #endif
71: /* Register package finalizer */
72: PetscCall(PetscRegisterFinalize(PetscViewerFinalizePackage));
73: PetscFunctionReturn(PETSC_SUCCESS);
74: }
76: /*@
77: PetscViewerDestroy - Destroys a `PetscViewer`.
79: Collective
81: Input Parameter:
82: . viewer - the `PetscViewer` to be destroyed.
84: Level: beginner
86: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`
87: @*/
88: PetscErrorCode PetscViewerDestroy(PetscViewer *viewer)
89: {
90: PetscFunctionBegin;
91: if (!*viewer) PetscFunctionReturn(PETSC_SUCCESS);
94: PetscCall(PetscViewerFlush(*viewer));
95: if (--((PetscObject)*viewer)->refct > 0) {
96: *viewer = NULL;
97: PetscFunctionReturn(PETSC_SUCCESS);
98: }
100: PetscCall(PetscObjectSAWsViewOff((PetscObject)*viewer));
101: PetscTryTypeMethod(*viewer, destroy);
102: PetscCall(PetscHeaderDestroy(viewer));
103: PetscFunctionReturn(PETSC_SUCCESS);
104: }
106: /*@C
107: PetscViewerAndFormatCreate - Creates a `PetscViewerAndFormat` struct.
109: Collective
111: Input Parameters:
112: + viewer - the viewer
113: - format - the format
115: Output Parameter:
116: . vf - viewer and format object
118: Level: developer
120: Notes:
121: This increases the reference count of the viewer.
123: Use `PetscViewerAndFormatDestroy()` to free the struct
125: This is used as the context variable for many of the `TS`, `SNES`, and `KSP` monitor functions
127: This construct exists because it allows one to keep track of the use of a `PetscViewerFormat` without requiring the
128: format in the viewer to be permanently changed.
130: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`,
131: `PetscViewerDrawOpen()`, `PetscViewerAndFormatDestroy()`
132: @*/
133: PetscErrorCode PetscViewerAndFormatCreate(PetscViewer viewer, PetscViewerFormat format, PetscViewerAndFormat **vf)
134: {
135: PetscFunctionBegin;
136: PetscCall(PetscObjectReference((PetscObject)viewer));
137: PetscCall(PetscNew(vf));
138: (*vf)->viewer = viewer;
139: (*vf)->format = format;
140: (*vf)->data = NULL;
141: PetscFunctionReturn(PETSC_SUCCESS);
142: }
144: /*@C
145: PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct created with `PetscViewerAndFormatCreate()`
147: Collective
149: Input Parameter:
150: . vf - the `PetscViewerAndFormat` to be destroyed.
152: Level: developer
154: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerAndFormatCreate()`, `PetscViewerSocketOpen()`,
155: `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`
156: @*/
157: PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf)
158: {
159: PetscFunctionBegin;
160: PetscCall(PetscViewerDestroy(&(*vf)->viewer));
161: if ((*vf)->data_destroy) PetscCall((*vf)->data_destroy(&(*vf)->data));
162: PetscCall(PetscFree(*vf));
163: PetscFunctionReturn(PETSC_SUCCESS);
164: }
166: /*@
167: PetscViewerGetType - Returns the type of a `PetscViewer`.
169: Not Collective
171: Input Parameter:
172: . viewer - the `PetscViewer`
174: Output Parameter:
175: . type - `PetscViewerType`
177: Level: intermediate
179: Note:
180: `PetscViewerType` is actually a string
182: .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`
183: @*/
184: PetscErrorCode PetscViewerGetType(PetscViewer viewer, PetscViewerType *type)
185: {
186: PetscFunctionBegin;
188: PetscAssertPointer(type, 2);
189: *type = ((PetscObject)viewer)->type_name;
190: PetscFunctionReturn(PETSC_SUCCESS);
191: }
193: /*@
194: PetscViewerSetOptionsPrefix - Sets the prefix used for searching for
195: `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
197: Logically Collective
199: Input Parameters:
200: + viewer - the `PetscViewer` context
201: - prefix - the prefix to prepend to all option names
203: Note:
204: A hyphen (-) must NOT be given at the beginning of the prefix name.
205: The first character of all runtime options is AUTOMATICALLY the hyphen.
207: Level: advanced
209: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSetFromOptions()`, `PetscViewerAppendOptionsPrefix()`
210: @*/
211: PetscErrorCode PetscViewerSetOptionsPrefix(PetscViewer viewer, const char prefix[])
212: {
213: PetscFunctionBegin;
215: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)viewer, prefix));
216: PetscFunctionReturn(PETSC_SUCCESS);
217: }
219: /*@
220: PetscViewerAppendOptionsPrefix - Appends to the prefix used for searching for
221: `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
223: Logically Collective
225: Input Parameters:
226: + viewer - the `PetscViewer` context
227: - prefix - the prefix to prepend to all option names
229: Level: advanced
231: Note:
232: A hyphen (-) must NOT be given at the beginning of the prefix name.
233: The first character of all runtime options is AUTOMATICALLY the hyphen.
235: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerGetOptionsPrefix()`, `PetscViewerSetOptionsPrefix()`
236: @*/
237: PetscErrorCode PetscViewerAppendOptionsPrefix(PetscViewer viewer, const char prefix[])
238: {
239: PetscFunctionBegin;
241: PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)viewer, prefix));
242: PetscFunctionReturn(PETSC_SUCCESS);
243: }
245: /*@
246: PetscViewerGetOptionsPrefix - Gets the prefix used for searching for
247: `PetscViewer` options in the database during `PetscViewerSetFromOptions()`.
249: Not Collective
251: Input Parameter:
252: . viewer - the `PetscViewer` context
254: Output Parameter:
255: . prefix - pointer to the prefix string used
257: Level: advanced
259: Fortran Notes:
260: The user should pass in a string 'prefix' of sufficient length to hold the prefix.
262: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()`, `PetscViewerSetOptionsPrefix()`
263: @*/
264: PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[])
265: {
266: PetscFunctionBegin;
268: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix));
269: PetscFunctionReturn(PETSC_SUCCESS);
270: }
272: /*@
273: PetscViewerSetUp - Sets up the internal viewer data structures for the later use.
275: Collective
277: Input Parameter:
278: . viewer - the `PetscViewer` context
280: Level: advanced
282: Note:
283: For basic use of the `PetscViewer` classes the user need not explicitly call
284: `PetscViewerSetUp()`, since these actions will happen automatically.
286: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()`
287: @*/
288: PetscErrorCode PetscViewerSetUp(PetscViewer viewer)
289: {
290: PetscFunctionBegin;
292: if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
293: PetscTryTypeMethod(viewer, setup);
294: viewer->setupcalled = PETSC_TRUE;
295: PetscFunctionReturn(PETSC_SUCCESS);
296: }
298: /*@
299: PetscViewerViewFromOptions - View from the viewer based on options in the options database
301: Collective
303: Input Parameters:
304: + A - the `PetscViewer` context
305: . obj - Optional object that provides the prefix for the option names
306: - name - command line option
308: Level: intermediate
310: Note:
311: See `PetscObjectViewFromOptions()` for details on the viewers and formats support via this interface
313: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerView`, `PetscObjectViewFromOptions()`, `PetscViewerCreate()`
314: @*/
315: PetscErrorCode PetscViewerViewFromOptions(PetscViewer A, PetscObject obj, const char name[])
316: {
317: PetscFunctionBegin;
319: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
320: PetscFunctionReturn(PETSC_SUCCESS);
321: }
323: /*@
324: PetscViewerView - Visualizes a viewer object.
326: Collective
328: Input Parameters:
329: + v - the viewer to be viewed
330: - viewer - visualization context
332: Level: beginner
334: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
335: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerLoad()`
336: @*/
337: PetscErrorCode PetscViewerView(PetscViewer v, PetscViewer viewer)
338: {
339: PetscBool iascii;
340: PetscViewerFormat format;
341: #if defined(PETSC_HAVE_SAWS)
342: PetscBool issaws;
343: #endif
345: PetscFunctionBegin;
348: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer));
350: PetscCheckSameComm(v, 1, viewer, 2);
352: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
353: #if defined(PETSC_HAVE_SAWS)
354: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
355: #endif
356: if (iascii) {
357: PetscCall(PetscViewerGetFormat(viewer, &format));
358: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)v, viewer));
359: if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
360: if (v->format) PetscCall(PetscViewerASCIIPrintf(viewer, " Viewer format = %s\n", PetscViewerFormats[v->format]));
361: PetscCall(PetscViewerASCIIPushTab(viewer));
362: PetscTryTypeMethod(v, view, viewer);
363: PetscCall(PetscViewerASCIIPopTab(viewer));
364: }
365: #if defined(PETSC_HAVE_SAWS)
366: } else if (issaws) {
367: if (!((PetscObject)v)->amsmem) {
368: PetscCall(PetscObjectViewSAWs((PetscObject)v, viewer));
369: PetscTryTypeMethod(v, view, viewer);
370: }
371: #endif
372: }
373: PetscFunctionReturn(PETSC_SUCCESS);
374: }
376: /*@C
377: PetscViewerRead - Reads data from a `PetscViewer`
379: Collective
381: Input Parameters:
382: + viewer - The viewer
383: . data - Location to write the data, treated as an array of the type defined by `datatype`
384: . num - Number of items of data to read
385: - dtype - Type of data to read
387: Output Parameter:
388: . count - number of items of data actually read, or `NULL`
390: Level: beginner
392: Notes:
393: If datatype is `PETSC_STRING` and `num` is negative, reads until a newline character is found,
394: until a maximum of (-num - 1) chars.
396: Only certain viewers, such as `PETSCVIEWERBINARY` can be read from, see `PetscViewerReadable()`
398: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`,
399: `PetscViewerReadable()`, `PetscViewerBinaryGetDescriptor()`,
400: `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`
401: @*/
402: PetscErrorCode PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
403: {
404: PetscFunctionBegin;
406: if (dtype == PETSC_STRING) {
407: PetscInt c, i = 0, cnt;
408: char *s = (char *)data;
409: if (num >= 0) {
410: for (c = 0; c < num; c++) {
411: /* Skip leading whitespaces */
412: do {
413: PetscUseTypeMethod(viewer, read, &s[i], 1, &cnt, PETSC_CHAR);
414: if (!cnt) break;
415: } while (s[i] == '\n' || s[i] == '\t' || s[i] == ' ' || s[i] == '\0' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r');
416: i++;
417: /* Read strings one char at a time */
418: do {
419: PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR);
420: if (!cnt) break;
421: } while (s[i - 1] != '\n' && s[i - 1] != '\t' && s[i - 1] != ' ' && s[i - 1] != '\0' && s[i - 1] != '\v' && s[i - 1] != '\f' && s[i - 1] != '\r');
422: /* Terminate final string */
423: if (c == num - 1) s[i - 1] = '\0';
424: }
425: } else {
426: /* Read until a \n is encountered (-num is the max size allowed) */
427: do {
428: PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR);
429: if (i == -num || !cnt) break;
430: } while (s[i - 1] != '\n');
431: /* Terminate final string */
432: s[i - 1] = '\0';
433: c = i;
434: }
435: if (count) *count = c;
436: else PetscCheck(c >= num, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %" PetscInt_FMT " < %" PetscInt_FMT " strings", c, num);
437: } else PetscUseTypeMethod(viewer, read, data, num, count, dtype);
438: PetscFunctionReturn(PETSC_SUCCESS);
439: }
441: /*@
442: PetscViewerReadable - Return a flag whether the viewer can be read from with `PetscViewerRead()`
444: Not Collective
446: Input Parameter:
447: . viewer - the `PetscViewer` context
449: Output Parameter:
450: . flg - `PETSC_TRUE` if the viewer is readable, `PETSC_FALSE` otherwise
452: Level: intermediate
454: Note:
455: `PETSC_TRUE` means that viewer's `PetscViewerType` supports reading, that is `PetscViewerRead()`, (this holds e.g. for `PETSCVIEWERBINARY`)
456: and the viewer is in a mode allowing reading, i.e. `PetscViewerFileGetMode()`
457: returns one of `FILE_MODE_READ`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
459: .seealso: [](sec_viewers), `PetscViewerRead()`, `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
460: @*/
461: PetscErrorCode PetscViewerReadable(PetscViewer viewer, PetscBool *flg)
462: {
463: PetscFileMode mode;
464: PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
466: PetscFunctionBegin;
468: PetscAssertPointer(flg, 2);
469: PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
470: *flg = PETSC_FALSE;
471: if (!f) PetscFunctionReturn(PETSC_SUCCESS);
472: PetscCall((*f)(viewer, &mode));
473: switch (mode) {
474: case FILE_MODE_READ:
475: case FILE_MODE_UPDATE:
476: case FILE_MODE_APPEND_UPDATE:
477: *flg = PETSC_TRUE;
478: default:
479: break;
480: }
481: PetscFunctionReturn(PETSC_SUCCESS);
482: }
484: /*@
485: PetscViewerWritable - Return a flag whether the viewer can be written to with `PetscViewerWrite()`
487: Not Collective
489: Input Parameter:
490: . viewer - the `PetscViewer` context
492: Output Parameter:
493: . flg - `PETSC_TRUE` if the viewer is writable, `PETSC_FALSE` otherwise
495: Level: intermediate
497: Note:
498: `PETSC_TRUE` means viewer is in a mode allowing writing, i.e. `PetscViewerFileGetMode()`
499: returns one of `FILE_MODE_WRITE`, `FILE_MODE_APPEND`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
501: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
502: @*/
503: PetscErrorCode PetscViewerWritable(PetscViewer viewer, PetscBool *flg)
504: {
505: PetscFileMode mode;
506: PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
508: PetscFunctionBegin;
510: PetscAssertPointer(flg, 2);
511: PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
512: *flg = PETSC_TRUE;
513: if (!f) PetscFunctionReturn(PETSC_SUCCESS);
514: PetscCall((*f)(viewer, &mode));
515: if (mode == FILE_MODE_READ) *flg = PETSC_FALSE;
516: PetscFunctionReturn(PETSC_SUCCESS);
517: }
519: /*@
520: PetscViewerCheckReadable - Check whether the viewer can be read from, generates an error if not
522: Collective
524: Input Parameter:
525: . viewer - the `PetscViewer` context
527: Level: intermediate
529: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
530: @*/
531: PetscErrorCode PetscViewerCheckReadable(PetscViewer viewer)
532: {
533: PetscBool flg;
535: PetscFunctionBegin;
537: PetscCall(PetscViewerReadable(viewer, &flg));
538: PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support reading, or is not in reading mode (FILE_MODE_READ, FILE_MODE_UPDATE, FILE_MODE_APPEND_UPDATE)");
539: PetscFunctionReturn(PETSC_SUCCESS);
540: }
542: /*@
543: PetscViewerCheckWritable - Check whether the viewer can be written to, generates an error if not
545: Collective
547: Input Parameter:
548: . viewer - the `PetscViewer` context
550: Level: intermediate
552: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
553: @*/
554: PetscErrorCode PetscViewerCheckWritable(PetscViewer viewer)
555: {
556: PetscBool flg;
558: PetscFunctionBegin;
560: PetscCall(PetscViewerWritable(viewer, &flg));
561: PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode");
562: PetscFunctionReturn(PETSC_SUCCESS);
563: }