xref: /petsc/src/sys/classes/viewer/interface/dupl.c (revision a62913d391e8303b4ae66efcf3348014a11cdd93)
15c6c1daeSBarry Smith 
2af0996ceSBarry Smith #include <petsc/private/viewerimpl.h>  /*I "petscviewer.h" I*/
35c6c1daeSBarry Smith 
4b3fa1ec5SBarry Smith /*@C
53f08860eSBarry Smith    PetscViewerGetSubViewer - Creates a new PetscViewer (same type as the old)
63f08860eSBarry Smith     that lives on a subcommunicator
75c6c1daeSBarry Smith 
85c6c1daeSBarry Smith     Collective on PetscViewer
95c6c1daeSBarry Smith 
105c6c1daeSBarry Smith    Input Parameter:
113f08860eSBarry Smith .  viewer - the PetscViewer to be reproduced
125c6c1daeSBarry Smith 
135c6c1daeSBarry Smith    Output Parameter:
145c6c1daeSBarry Smith .  outviewer - new PetscViewer
155c6c1daeSBarry Smith 
165c6c1daeSBarry Smith    Level: advanced
175c6c1daeSBarry Smith 
1895452b02SPatrick Sanan    Notes:
19*a62913d3SBarry Smith     The output of the subviewers is synchronized against the original viewer. For example, if a
20*a62913d3SBarry Smith     viewer on two MPI ranks is decomposed into two subviewers, the output from the first viewer is
21*a62913d3SBarry Smith     all printed before the output from the second viewer. You must call PetscViewerFlush() after
22*a62913d3SBarry Smith     the call to PetscViewerRestoreSubViewer().
23*a62913d3SBarry Smith 
24*a62913d3SBarry Smith     Call PetscViewerRestoreSubViewer() to destroy this PetscViewer, NOT PetscViewerDestroy()
255c6c1daeSBarry Smith 
265c6c1daeSBarry Smith      This is most commonly used to view a sequential object that is part of a
275c6c1daeSBarry Smith     parallel object. For example block Jacobi PC view could use this to obtain a
285c6c1daeSBarry Smith     PetscViewer that is used with the sequential KSP on one block of the preconditioner.
295c6c1daeSBarry Smith 
30e5afcf28SBarry Smith     Between the calls to PetscViewerGetSubViewer() and PetscViewerRestoreSubViewer() the original
31e5afcf28SBarry Smith     viewer should not be used
32e5afcf28SBarry Smith 
33e5afcf28SBarry Smith     PETSCVIEWERDRAW and PETSCVIEWERBINARY only support returning a singleton viewer on rank 0,
34e5afcf28SBarry Smith     all other ranks will return a NULL viewer
35e5afcf28SBarry Smith 
36e5afcf28SBarry Smith   Developer Notes:
37e5afcf28SBarry Smith     There is currently incomplete error checking that the user does not use the original viewer between the
38e5afcf28SBarry Smith     the calls to PetscViewerGetSubViewer() and PetscViewerRestoreSubViewer(). If the user does there
39e5afcf28SBarry Smith     could be errors in the viewing that go undetected or crash the code.
40e5afcf28SBarry Smith 
41*a62913d3SBarry Smith     It would be nice if the call to PetscViewerFlush() was not required and was handled by
42*a62913d3SBarry Smith     PetscViewerRestoreSubViewer()
43*a62913d3SBarry Smith 
443f08860eSBarry Smith .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerRestoreSubViewer()
455c6c1daeSBarry Smith @*/
463f08860eSBarry Smith PetscErrorCode  PetscViewerGetSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
475c6c1daeSBarry Smith {
485c6c1daeSBarry Smith   PetscErrorCode ierr;
495c6c1daeSBarry Smith   PetscMPIInt    size;
505c6c1daeSBarry Smith 
515c6c1daeSBarry Smith   PetscFunctionBegin;
525c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
535c6c1daeSBarry Smith   PetscValidPointer(outviewer,2);
54ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
555c6c1daeSBarry Smith   if (size == 1) {
565c6c1daeSBarry Smith     ierr       = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
575c6c1daeSBarry Smith     *outviewer = viewer;
58559f443fSBarry Smith   } else if (viewer->ops->getsubviewer) {
59559f443fSBarry Smith     ierr = (*viewer->ops->getsubviewer)(viewer,comm,outviewer);CHKERRQ(ierr);
603f08860eSBarry Smith   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
615c6c1daeSBarry Smith   PetscFunctionReturn(0);
625c6c1daeSBarry Smith }
635c6c1daeSBarry Smith 
64b3fa1ec5SBarry Smith /*@C
653f08860eSBarry Smith    PetscViewerRestoreSubViewer - Restores a new PetscViewer obtained with PetscViewerGetSubViewer().
665c6c1daeSBarry Smith 
675c6c1daeSBarry Smith     Collective on PetscViewer
685c6c1daeSBarry Smith 
695c6c1daeSBarry Smith    Input Parameters:
703f08860eSBarry Smith +  viewer - the PetscViewer that was reproduced
715c6c1daeSBarry Smith -  outviewer - new PetscViewer
725c6c1daeSBarry Smith 
735c6c1daeSBarry Smith    Level: advanced
745c6c1daeSBarry Smith 
7595452b02SPatrick Sanan    Notes:
7695452b02SPatrick Sanan     Call PetscViewerGetSubViewer() to get this PetscViewer, NOT PetscViewerCreate()
775c6c1daeSBarry Smith 
783f08860eSBarry Smith .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerGetSubViewer()
795c6c1daeSBarry Smith @*/
803f08860eSBarry Smith PetscErrorCode  PetscViewerRestoreSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
815c6c1daeSBarry Smith {
825c6c1daeSBarry Smith   PetscErrorCode ierr;
835c6c1daeSBarry Smith   PetscMPIInt    size;
845c6c1daeSBarry Smith 
855c6c1daeSBarry Smith   PetscFunctionBegin;
865c6c1daeSBarry Smith   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
875c6c1daeSBarry Smith 
88ce94432eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
895c6c1daeSBarry Smith   if (size == 1) {
905c6c1daeSBarry Smith     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
91c6228bbaSLisandro Dalcin     if (outviewer) *outviewer = NULL;
92559f443fSBarry Smith   } else if (viewer->ops->restoresubviewer) {
93559f443fSBarry Smith     ierr = (*viewer->ops->restoresubviewer)(viewer,comm,outviewer);CHKERRQ(ierr);
945c6c1daeSBarry Smith   }
955c6c1daeSBarry Smith   PetscFunctionReturn(0);
965c6c1daeSBarry Smith }
975c6c1daeSBarry Smith 
98