Actual source code: dupl.c
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: {
50: if (viewer->ops->getsubviewer) {
51: (*viewer->ops->getsubviewer)(viewer,comm,outviewer);
52: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
53: return 0;
54: }
56: /*@C
57: PetscViewerRestoreSubViewer - Restores a new PetscViewer obtained with PetscViewerGetSubViewer().
59: Collective on PetscViewer
61: Input Parameters:
62: + viewer - the PetscViewer that was reproduced
63: - outviewer - new PetscViewer
65: Level: advanced
67: Notes:
68: Call PetscViewerGetSubViewer() to get this PetscViewer, NOT PetscViewerCreate()
70: .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerGetSubViewer()
71: @*/
72: PetscErrorCode PetscViewerRestoreSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
73: {
76: if (viewer->ops->restoresubviewer) {
77: (*viewer->ops->restoresubviewer)(viewer,comm,outviewer);
78: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot restore SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
79: return 0;
80: }