xref: /petsc/src/sys/classes/viewer/interface/dupl.c (revision 60225df5d8469840be2bf9c1f64795a92b19f3c2)
1 
2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
3 
4 /*@C
5   PetscViewerGetSubViewer - Creates a new `PetscViewer` (same type as the old)
6   that lives on a subcommunicator of the original viewer's communicator
7 
8   Collective
9 
10   Input Parameter:
11 . viewer - the `PetscViewer` to be reproduced
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   Between the calls to `PetscViewerGetSubViewer()` and `PetscViewerRestoreSubViewer()` the original
31   viewer should not be used
32 
33   `PETSCVIEWERDRAW` and `PETSCVIEWERBINARY` only support returning a singleton viewer on MPI rank 0,
34   all other ranks will return a `NULL` viewer
35 
36   Developer Notes:
37   There is currently incomplete error checking to ensure the user does not use the original viewer between the
38   the calls to `PetscViewerGetSubViewer()` and `PetscViewerRestoreSubViewer()`. If the user does there
39   could be errors in the viewing that go undetected or crash the code.
40 
41   It would be nice if the call to `PetscViewerFlush()` was not required and was handled by
42   `PetscViewerRestoreSubViewer()`
43 
44 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewerRestoreSubViewer()`
45 @*/
46 PetscErrorCode PetscViewerGetSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
47 {
48   PetscFunctionBegin;
49   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
50   PetscValidPointer(outviewer, 3);
51   PetscUseTypeMethod(viewer, getsubviewer, comm, outviewer);
52   PetscFunctionReturn(PETSC_SUCCESS);
53 }
54 
55 /*@C
56   PetscViewerRestoreSubViewer - Restores a  `PetscViewer` obtained with `PetscViewerGetSubViewer()`.
57 
58   Collective
59 
60   Input Parameters:
61 + viewer    - the `PetscViewer` that was reproduced
62 - outviewer - the subviewer to be returned
63 
64   Level: advanced
65 
66 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewerGetSubViewer()`
67 @*/
68 PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
69 {
70   PetscFunctionBegin;
71   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
72 
73   PetscUseTypeMethod(viewer, restoresubviewer, comm, outviewer);
74   PetscFunctionReturn(PETSC_SUCCESS);
75 }
76