Actual source code: dupl.c
petsc-3.14.6 2021-03-30
2: #include <petsc/private/viewerimpl.h>
4: /*@C
5: PetscViewerGetSubViewer - Creates a new PetscViewer (same type as the old)
6: that lives on a subcommunicator
8: Collective on PetscViewer
10: Input Parameter:
11: . viewer - the PetscViewer to be reproduced
13: Output Parameter:
14: . outviewer - new PetscViewer
16: Level: advanced
18: Notes:
19: The output of the subviewers is synchronized against the original viewer. For example, if a
20: viewer on two MPI ranks 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().
24: Call PetscViewerRestoreSubViewer() to destroy this PetscViewer, NOT PetscViewerDestroy()
26: This is most commonly used to view a sequential object that is part of a
27: parallel object. For example block Jacobi PC view could use this to obtain a
28: PetscViewer that is used with the sequential KSP on one block of the preconditioner.
30: Between the calls to PetscViewerGetSubViewer() and PetscViewerRestoreSubViewer() the original
31: viewer should not be used
33: PETSCVIEWERDRAW and PETSCVIEWERBINARY only support returning a singleton viewer on rank 0,
34: all other ranks will return a NULL viewer
36: Developer Notes:
37: There is currently incomplete error checking that 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.
41: It would be nice if the call to PetscViewerFlush() was not required and was handled by
42: PetscViewerRestoreSubViewer()
44: .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerRestoreSubViewer()
45: @*/
46: PetscErrorCode PetscViewerGetSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
47: {
53: if (viewer->ops->getsubviewer) {
54: (*viewer->ops->getsubviewer)(viewer,comm,outviewer);
55: } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
56: return(0);
57: }
59: /*@C
60: PetscViewerRestoreSubViewer - Restores a new PetscViewer obtained with PetscViewerGetSubViewer().
62: Collective on PetscViewer
64: Input Parameters:
65: + viewer - the PetscViewer that was reproduced
66: - outviewer - new PetscViewer
68: Level: advanced
70: Notes:
71: Call PetscViewerGetSubViewer() to get this PetscViewer, NOT PetscViewerCreate()
73: .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerGetSubViewer()
74: @*/
75: PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
76: {
81: if (viewer->ops->restoresubviewer) {
82: (*viewer->ops->restoresubviewer)(viewer,comm,outviewer);
83: } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
84: return(0);
85: }