xref: /petsc/src/sys/classes/viewer/interface/dupl.c (revision e907feaad8a9ad15ff003b1a1f8acb2ecb25e843)
1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
2 
3 /*@C
4   PetscViewerGetSubViewer - Creates a new `PetscViewer` (same type as the old)
5   that lives on a subcommunicator of the original viewer's communicator
6 
7   Collective
8 
9   Input Parameters:
10 + viewer - the `PetscViewer` to be reproduced
11 - comm   - the sub communicator to use
12 
13   Output Parameter:
14 . outviewer - new `PetscViewer`
15 
16   Level: advanced
17 
18   Notes:
19   The output of the subviewers is synchronized against the original viewer. For example, if a
20   viewer on two MPI processes is decomposed into two subviewers, the output from the first viewer is
21   all printed before the output from the second viewer. You must call `PetscViewerFlush()` after
22   the call to `PetscViewerRestoreSubViewer()`.
23 
24   Call `PetscViewerRestoreSubViewer()` to destroy this `PetscViewer`, NOT `PetscViewerDestroy()`
25 
26   This is most commonly used to view a sequential object that is part of a
27   parallel object. For example `PCView()` on a `PCBJACOBI` could use this to obtain a
28   `PetscViewer` that is used with the sequential `KSP` on one block of the preconditioner.
29 
30   `PetscViewerFlush()` is run automatically with `PetscViewerRestoreSubViewer()`
31 
32   `PETSCVIEWERDRAW` and `PETSCVIEWERBINARY` only support returning a singleton viewer on MPI rank 0,
33   all other ranks will return a `NULL` viewer
34 
35   For `PETSCVIEWERASCII` the viewers behavior is as follows\:
36 .vb
37   Recursive calls are allowed
38   A call to `PetscViewerASCIIPrintf()` on a subviewer results in output for the first MPI process in the `outviewer` only
39   Calls to  `PetscViewerASCIIPrintf()` and `PetscViewerASCIISynchronizedPrintf()` are immediately passed up through all
40   the parent viewers to the higher most parent with `PetscViewerASCIISynchronizedPrintf()` where they are immediately
41   printed on the first MPI process or stashed on the other processes.
42   At the higher most `PetscViewerRestoreSubViewer()` the viewer is automatically flushed with `PetscViewerFlush()`
43 .ve
44 
45   Developer Notes:
46   There is currently incomplete error checking to ensure the user does not use the original viewer between the
47   the calls to `PetscViewerGetSubViewer()` and `PetscViewerRestoreSubViewer()`. If the user does there
48   could be errors in the viewing that go undetected or crash the code.
49 
50 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
51           `PetscViewerFlush()`, `PetscViewerRestoreSubViewer()`
52 @*/
53 PetscErrorCode PetscViewerGetSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
54 {
55   PetscFunctionBegin;
56   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
57   PetscAssertPointer(outviewer, 3);
58   PetscUseTypeMethod(viewer, getsubviewer, comm, outviewer);
59   PetscFunctionReturn(PETSC_SUCCESS);
60 }
61 
62 /*@C
63   PetscViewerRestoreSubViewer - Restores a  `PetscViewer` obtained with `PetscViewerGetSubViewer()`.
64 
65   Collective
66 
67   Input Parameters:
68 + viewer    - the `PetscViewer` that was reproduced
69 . comm      - the sub communicator
70 - outviewer - the subviewer to be returned
71 
72   Level: advanced
73 
74   Note:
75   Automatically runs `PetscViewerFlush()` on the outter viewer
76 
77 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewerGetSubViewer()`,
78           `PetscViewerFlush()`
79 @*/
80 PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
81 {
82   PetscFunctionBegin;
83   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
84 
85   PetscUseTypeMethod(viewer, restoresubviewer, comm, outviewer);
86   PetscFunctionReturn(PETSC_SUCCESS);
87 }
88