Actual source code: view.c
1: #include <petsc/private/viewerimpl.h>
3: PetscClassId PETSC_VIEWER_CLASSID;
5: static PetscBool PetscViewerPackageInitialized = PETSC_FALSE;
7: /*@
8: PetscViewerFinalizePackage - This function destroys any global objects created in PETSc viewers. It is
9: called from `PetscFinalize()`.
11: Level: developer
13: .seealso: [](sec_viewers), `PetscViewer`, `PetscFinalize()`, `PetscViewerInitializePackage()`
14: @*/
15: PetscErrorCode PetscViewerFinalizePackage(void)
16: {
17: PetscFunctionBegin;
18: if (Petsc_Viewer_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_keyval));
19: if (Petsc_Viewer_Stdout_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stdout_keyval));
20: if (Petsc_Viewer_Stderr_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Stderr_keyval));
21: if (Petsc_Viewer_Binary_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Binary_keyval));
22: if (Petsc_Viewer_Draw_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Draw_keyval));
23: #if PetscDefined(HAVE_HDF5)
24: if (Petsc_Viewer_HDF5_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_HDF5_keyval));
25: #endif
26: #if PetscDefined(USE_SOCKETVIEWER)
27: if (Petsc_Viewer_Socket_keyval != MPI_KEYVAL_INVALID) PetscCallMPI(MPI_Comm_free_keyval(&Petsc_Viewer_Socket_keyval));
28: #endif
29: PetscCall(PetscFunctionListDestroy(&PetscViewerList));
30: PetscViewerPackageInitialized = PETSC_FALSE;
31: PetscViewerRegisterAllCalled = PETSC_FALSE;
32: PetscFunctionReturn(PETSC_SUCCESS);
33: }
35: /*@
36: PetscViewerInitializePackage - This function initializes everything in the `PetscViewer` package.
38: Level: developer
40: .seealso: [](sec_viewers), `PetscViewer`, `PetscInitialize()`, `PetscViewerFinalizePackage()`
41: @*/
42: PetscErrorCode PetscViewerInitializePackage(void)
43: {
44: char logList[256];
45: PetscBool opt, pkg;
47: PetscFunctionBegin;
48: if (PetscViewerPackageInitialized) PetscFunctionReturn(PETSC_SUCCESS);
49: PetscViewerPackageInitialized = PETSC_TRUE;
50: /* Register Classes */
51: PetscCall(PetscClassIdRegister("Viewer", &PETSC_VIEWER_CLASSID));
52: /* Register Constructors */
53: PetscCall(PetscViewerRegisterAll());
54: /* Process Info */
55: {
56: PetscClassId classids[1];
58: classids[0] = PETSC_VIEWER_CLASSID;
59: PetscCall(PetscInfoProcessClass("viewer", 1, classids));
60: }
61: /* Process summary exclusions */
62: PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
63: if (opt) {
64: PetscCall(PetscStrInList("viewer", logList, ',', &pkg));
65: if (pkg) PetscCall(PetscLogEventExcludeClass(PETSC_VIEWER_CLASSID));
66: }
67: #if PetscDefined(HAVE_MATHEMATICA)
68: PetscCall(PetscViewerMathematicaInitializePackage());
69: #endif
70: /* Register package finalizer */
71: PetscCall(PetscRegisterFinalize(PetscViewerFinalizePackage));
72: PetscFunctionReturn(PETSC_SUCCESS);
73: }
75: /*@
76: PetscViewerDestroy - Destroys a `PetscViewer`.
78: Collective
80: Input Parameter:
81: . viewer - the `PetscViewer` to be destroyed.
83: Level: beginner
85: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`
86: @*/
87: PetscErrorCode PetscViewerDestroy(PetscViewer *viewer)
88: {
89: PetscFunctionBegin;
90: if (!*viewer) PetscFunctionReturn(PETSC_SUCCESS);
93: PetscCall(PetscViewerFlush(*viewer));
94: if (--((PetscObject)*viewer)->refct > 0) {
95: *viewer = NULL;
96: PetscFunctionReturn(PETSC_SUCCESS);
97: }
99: PetscCall(PetscObjectSAWsViewOff((PetscObject)*viewer));
100: PetscTryTypeMethod(*viewer, destroy);
101: PetscCall(PetscHeaderDestroy(viewer));
102: PetscFunctionReturn(PETSC_SUCCESS);
103: }
105: /*@
106: PetscViewerAndFormatCreate - Creates a `PetscViewerAndFormat` struct.
108: Collective
110: Input Parameters:
111: + viewer - the viewer
112: - format - the format
114: Output Parameter:
115: . vf - viewer and format object
117: Level: developer
119: Notes:
120: This increases the reference count of the viewer.
122: Use `PetscViewerAndFormatDestroy()` to free the struct
124: This is used as the context variable for many of the `TS`, `SNES`, and `KSP` monitor functions
126: This construct exists because it allows one to keep track of the use of a `PetscViewerFormat` without requiring the
127: format in the viewer to be permanently changed.
129: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerCreate()`,
130: `PetscViewerDrawOpen()`, `PetscViewerAndFormatDestroy()`
131: @*/
132: PetscErrorCode PetscViewerAndFormatCreate(PetscViewer viewer, PetscViewerFormat format, PetscViewerAndFormat **vf)
133: {
134: PetscFunctionBegin;
135: PetscCall(PetscObjectReference((PetscObject)viewer));
136: PetscCall(PetscNew(vf));
137: (*vf)->viewer = viewer;
138: (*vf)->format = format;
139: (*vf)->data = NULL;
140: PetscFunctionReturn(PETSC_SUCCESS);
141: }
143: /*@
144: PetscViewerAndFormatDestroy - Destroys a `PetscViewerAndFormat` struct created with `PetscViewerAndFormatCreate()`
146: Collective
148: Input Parameter:
149: . vf - the `PetscViewerAndFormat` to be destroyed.
151: Level: developer
153: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAndFormat`, `PetscViewerFormat`, `PetscViewerAndFormatCreate()`, `PetscViewerSocketOpen()`,
154: `PetscViewerASCIIOpen()`, `PetscViewerCreate()`, `PetscViewerDrawOpen()`
155: @*/
156: PetscErrorCode PetscViewerAndFormatDestroy(PetscViewerAndFormat **vf)
157: {
158: PetscFunctionBegin;
159: if (!*vf) PetscFunctionReturn(PETSC_SUCCESS);
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: `type` should not be retained for later use as it will be an invalid pointer if the `PetscViewerType` of `viewer` is changed.
182: .seealso: [](sec_viewers), `PetscViewerType`, `PetscViewer`, `PetscViewerCreate()`, `PetscViewerSetType()`, `PetscObjectTypeCompare()`, `PetscObjectTypeCompareAny()`
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: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerAppendOptionsPrefix()`, `PetscViewerSetOptionsPrefix()`
260: @*/
261: PetscErrorCode PetscViewerGetOptionsPrefix(PetscViewer viewer, const char *prefix[])
262: {
263: PetscFunctionBegin;
265: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)viewer, prefix));
266: PetscFunctionReturn(PETSC_SUCCESS);
267: }
269: /*@
270: PetscViewerSetUp - Sets up the internal viewer data structures for the later use.
272: Collective
274: Input Parameter:
275: . viewer - the `PetscViewer` context
277: Level: advanced
279: Note:
280: For basic use of the `PetscViewer` classes the user need not explicitly call
281: `PetscViewerSetUp()`, since these actions will happen automatically.
283: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerCreate()`, `PetscViewerDestroy()`
284: @*/
285: PetscErrorCode PetscViewerSetUp(PetscViewer viewer)
286: {
287: PetscFunctionBegin;
289: if (viewer->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
290: PetscTryTypeMethod(viewer, setup);
291: viewer->setupcalled = PETSC_TRUE;
292: PetscFunctionReturn(PETSC_SUCCESS);
293: }
295: /*@
296: PetscViewerViewFromOptions - View from the viewer based on options in the options database
298: Collective
300: Input Parameters:
301: + A - the `PetscViewer` context
302: . obj - optional object that provides the prefix for the option names, pass `NULL` to use the options prefix of `A`
303: - name - command line option
305: Options Database Key:
306: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`
308: Level: intermediate
310: Note:
311: This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
312: rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.
314: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerView()`, `PetscObjectViewFromOptions()`, `PetscViewerCreate()`, `PetscOptionsCreateViewer()`
315: @*/
316: PetscErrorCode PetscViewerViewFromOptions(PetscViewer A, PetscObject obj, const char name[])
317: {
318: PetscFunctionBegin;
320: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
321: PetscFunctionReturn(PETSC_SUCCESS);
322: }
324: /*@
325: PetscViewerView - Visualizes a viewer object.
327: Collective
329: Input Parameters:
330: + v - the viewer to be viewed
331: - viewer - visualization context
333: Level: beginner
335: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerPushFormat()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
336: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `PetscViewerLoad()`
337: @*/
338: PetscErrorCode PetscViewerView(PetscViewer v, PetscViewer viewer)
339: {
340: PetscBool isascii;
341: PetscViewerFormat format;
342: #if PetscDefined(HAVE_SAWS)
343: PetscBool issaws;
344: #endif
346: PetscFunctionBegin;
349: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)v), &viewer));
351: PetscCheckSameComm(v, 1, viewer, 2);
353: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
354: #if PetscDefined(HAVE_SAWS)
355: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws));
356: #endif
357: if (isascii) {
358: PetscCall(PetscViewerGetFormat(viewer, &format));
359: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)v, viewer));
360: if (format == PETSC_VIEWER_DEFAULT || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
361: if (v->format) PetscCall(PetscViewerASCIIPrintf(viewer, " Viewer format = %s\n", PetscViewerFormats[v->format]));
362: PetscCall(PetscViewerASCIIPushTab(viewer));
363: PetscTryTypeMethod(v, view, viewer);
364: PetscCall(PetscViewerASCIIPopTab(viewer));
365: }
366: #if PetscDefined(HAVE_SAWS)
367: } else if (issaws) {
368: if (!((PetscObject)v)->amsmem) {
369: PetscCall(PetscObjectViewSAWs((PetscObject)v, viewer));
370: PetscTryTypeMethod(v, view, viewer);
371: }
372: #endif
373: }
374: PetscFunctionReturn(PETSC_SUCCESS);
375: }
377: /*@
378: PetscViewerRead - Reads data from a `PetscViewer`
380: Collective
382: Input Parameters:
383: + viewer - The viewer
384: . data - Location to write the data, treated as an array of the type defined by `datatype`
385: . num - Number of items of data to read
386: - dtype - Type of data to read
388: Output Parameter:
389: . count - number of items of data actually read, or `NULL`
391: Level: beginner
393: Notes:
394: If datatype is `PETSC_STRING` and `num` is negative, reads until a newline character is found,
395: until a maximum of (-num - 1) chars.
397: Only certain viewers, such as `PETSCVIEWERBINARY` can be read from, see `PetscViewerReadable()`
399: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerASCIIOpen()`, `PetscViewerPushFormat()`, `PetscViewerDestroy()`,
400: `PetscViewerReadable()`, `PetscViewerBinaryGetDescriptor()`,
401: `PetscViewerBinaryGetInfoPointer()`, `PetscFileMode`
402: @*/
403: PetscErrorCode PetscViewerRead(PetscViewer viewer, void *data, PetscInt num, PetscInt *count, PetscDataType dtype)
404: {
405: PetscFunctionBegin;
407: if (dtype == PETSC_STRING) {
408: PetscInt c, i = 0, cnt;
409: char *s = (char *)data;
410: if (num >= 0) {
411: for (c = 0; c < num; c++) {
412: /* Skip leading whitespaces */
413: do {
414: PetscUseTypeMethod(viewer, read, &s[i], 1, &cnt, PETSC_CHAR);
415: if (!cnt) break;
416: } while (s[i] == '\n' || s[i] == '\t' || s[i] == ' ' || s[i] == '\0' || s[i] == '\v' || s[i] == '\f' || s[i] == '\r');
417: i++;
418: /* Read strings one char at a time */
419: do {
420: PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR);
421: if (!cnt) break;
422: } 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');
423: /* Terminate final string */
424: if (c == num - 1) s[i - 1] = '\0';
425: }
426: } else {
427: /* Read until a \n is encountered (-num is the max size allowed) */
428: do {
429: PetscUseTypeMethod(viewer, read, &s[i++], 1, &cnt, PETSC_CHAR);
430: if (i == -num || !cnt) break;
431: } while (s[i - 1] != '\n');
432: /* Terminate final string */
433: s[i - 1] = '\0';
434: c = i;
435: }
436: if (count) *count = c;
437: else PetscCheck(c >= num, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_READ, "Insufficient data, only read %" PetscInt_FMT " < %" PetscInt_FMT " strings", c, num);
438: } else PetscUseTypeMethod(viewer, read, data, num, count, dtype);
439: PetscFunctionReturn(PETSC_SUCCESS);
440: }
442: /*@
443: PetscViewerReadable - Return a flag whether the viewer can be read from with `PetscViewerRead()`
445: Not Collective
447: Input Parameter:
448: . viewer - the `PetscViewer` context
450: Output Parameter:
451: . flg - `PETSC_TRUE` if the viewer is readable, `PETSC_FALSE` otherwise
453: Level: intermediate
455: Note:
456: `PETSC_TRUE` means that viewer's `PetscViewerType` supports reading, that is `PetscViewerRead()`, (this holds e.g. for `PETSCVIEWERBINARY`)
457: and the viewer is in a mode allowing reading, i.e. `PetscViewerFileGetMode()`
458: returns one of `FILE_MODE_READ`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
460: .seealso: [](sec_viewers), `PetscViewerRead()`, `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
461: @*/
462: PetscErrorCode PetscViewerReadable(PetscViewer viewer, PetscBool *flg)
463: {
464: PetscFileMode mode;
465: PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
467: PetscFunctionBegin;
469: PetscAssertPointer(flg, 2);
470: PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
471: *flg = PETSC_FALSE;
472: if (!f) PetscFunctionReturn(PETSC_SUCCESS);
473: PetscCall((*f)(viewer, &mode));
474: switch (mode) {
475: case FILE_MODE_READ:
476: case FILE_MODE_UPDATE:
477: case FILE_MODE_APPEND_UPDATE:
478: *flg = PETSC_TRUE;
479: default:
480: break;
481: }
482: PetscFunctionReturn(PETSC_SUCCESS);
483: }
485: /*@
486: PetscViewerWritable - Return a flag whether the viewer can be written to with `PetscViewerWrite()`
488: Not Collective
490: Input Parameter:
491: . viewer - the `PetscViewer` context
493: Output Parameter:
494: . flg - `PETSC_TRUE` if the viewer is writable, `PETSC_FALSE` otherwise
496: Level: intermediate
498: Note:
499: `PETSC_TRUE` means viewer is in a mode allowing writing, i.e. `PetscViewerFileGetMode()`
500: returns one of `FILE_MODE_WRITE`, `FILE_MODE_APPEND`, `FILE_MODE_UPDATE`, `FILE_MODE_APPEND_UPDATE`.
502: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
503: @*/
504: PetscErrorCode PetscViewerWritable(PetscViewer viewer, PetscBool *flg)
505: {
506: PetscFileMode mode;
507: PetscErrorCode (*f)(PetscViewer, PetscFileMode *) = NULL;
509: PetscFunctionBegin;
511: PetscAssertPointer(flg, 2);
512: PetscCall(PetscObjectQueryFunction((PetscObject)viewer, "PetscViewerFileGetMode_C", &f));
513: *flg = PETSC_TRUE;
514: if (!f) PetscFunctionReturn(PETSC_SUCCESS);
515: PetscCall((*f)(viewer, &mode));
516: if (mode == FILE_MODE_READ) *flg = PETSC_FALSE;
517: PetscFunctionReturn(PETSC_SUCCESS);
518: }
520: /*@
521: PetscViewerCheckReadable - Check whether the viewer can be read from, generates an error if not
523: Collective
525: Input Parameter:
526: . viewer - the `PetscViewer` context
528: Level: intermediate
530: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerReadable()`, `PetscViewerCheckWritable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
531: @*/
532: PetscErrorCode PetscViewerCheckReadable(PetscViewer viewer)
533: {
534: PetscBool flg;
536: PetscFunctionBegin;
538: PetscCall(PetscViewerReadable(viewer, &flg));
539: 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)");
540: PetscFunctionReturn(PETSC_SUCCESS);
541: }
543: /*@
544: PetscViewerCheckWritable - Check whether the viewer can be written to, generates an error if not
546: Collective
548: Input Parameter:
549: . viewer - the `PetscViewer` context
551: Level: intermediate
553: .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerWritable()`, `PetscViewerCheckReadable()`, `PetscViewerCreate()`, `PetscViewerFileSetMode()`, `PetscViewerFileSetType()`
554: @*/
555: PetscErrorCode PetscViewerCheckWritable(PetscViewer viewer)
556: {
557: PetscBool flg;
559: PetscFunctionBegin;
561: PetscCall(PetscViewerWritable(viewer, &flg));
562: PetscCheck(flg, PetscObjectComm((PetscObject)viewer), PETSC_ERR_SUP, "Viewer doesn't support writing, or is in FILE_MODE_READ mode");
563: PetscFunctionReturn(PETSC_SUCCESS);
564: }