xref: /petsc/src/sys/classes/viewer/interface/dupl.c (revision a623e290c7eaa252b385564179837fe27521fbac)
1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
2 
3 /*@
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.
22 
23   Call `PetscViewerRestoreSubViewer()` to destroy this `PetscViewer`, NOT `PetscViewerDestroy()`
24 
25   This is most commonly used to view a sequential object that is part of a
26   parallel object. For example `PCView()` on a `PCBJACOBI` could use this to obtain a
27   `PetscViewer` that is used with the sequential `KSP` on one block of the preconditioner.
28 
29   `PetscViewerFlush()` is run automatically at the beginning of `PetscViewerGetSubViewer()` and with `PetscViewerRestoreSubViewer()`
30   for `PETSCVIEWERASCII`
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   Must be called by all MPI processes that share `viewer`, for processes that are not of interest you can pass
36   `PETSC_COMM_SELF`.
37 
38   For `PETSCVIEWERASCII` the viewers behavior is as follows\:
39 .vb
40   Recursive calls are allowed
41   A call to `PetscViewerASCIIPrintf()` on a subviewer results in output for the first MPI process in the `outviewer` only
42   Calls to  `PetscViewerASCIIPrintf()` and `PetscViewerASCIISynchronizedPrintf()` are immediately passed up through all
43   the parent viewers to the higher most parent with `PetscViewerASCIISynchronizedPrintf()` where they are immediately
44   printed on the first MPI process or stashed on the other processes.
45   At the higher most `PetscViewerRestoreSubViewer()` the viewer is automatically flushed with `PetscViewerFlush()`
46 .ve
47 
48   Developer Notes:
49   There is currently incomplete error checking to ensure the user does not use the original viewer between the
50   the calls to `PetscViewerGetSubViewer()` and `PetscViewerRestoreSubViewer()`. If the user does there
51   could be errors in the viewing that go undetected or crash the code.
52 
53   Complex use of this functionality with `PETSCVIEWERASCII` can result in output in unexpected order. This seems unavoidable.
54 
55 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`,
56           `PetscViewerFlush()`, `PetscViewerRestoreSubViewer()`
57 @*/
PetscViewerGetSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)58 PetscErrorCode PetscViewerGetSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
59 {
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
62   PetscAssertPointer(outviewer, 3);
63   PetscUseTypeMethod(viewer, getsubviewer, comm, outviewer);
64   PetscFunctionReturn(PETSC_SUCCESS);
65 }
66 
67 /*@
68   PetscViewerRestoreSubViewer - Restores a  `PetscViewer` obtained with `PetscViewerGetSubViewer()`.
69 
70   Collective
71 
72   Input Parameters:
73 + viewer    - the `PetscViewer` that was reproduced
74 . comm      - the sub communicator
75 - outviewer - the subviewer to be returned
76 
77   Level: advanced
78 
79   Notes:
80   Automatically runs `PetscViewerFlush()` on `outviewer`
81 
82   Must be called by all MPI processes that share `viewer`, for processes that are not of interest you can pass
83   `PETSC_COMM_SELF`.
84 
85 .seealso: [](sec_viewers), `PetscViewer`, `PetscViewerSocketOpen()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscViewerGetSubViewer()`,
86           `PetscViewerFlush()`
87 @*/
PetscViewerRestoreSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)88 PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer viewer, MPI_Comm comm, PetscViewer *outviewer)
89 {
90   PetscFunctionBegin;
91   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 1);
92 
93   PetscUseTypeMethod(viewer, restoresubviewer, comm, outviewer);
94   PetscFunctionReturn(PETSC_SUCCESS);
95 }
96