xref: /petsc/src/sys/classes/viewer/interface/dupl.c (revision 7eda4a2b655d50ced66764fb8992052c2fd6e7d7)
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
7 
8     Collective on PetscViewer
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     Call PetscViewerRestoreSubViewer() to return this PetscViewer, NOT PetscViewerDestroy()
20 
21      This is most commonly used to view a sequential object that is part of a
22     parallel object. For example block Jacobi PC view could use this to obtain a
23     PetscViewer that is used with the sequential KSP on one block of the preconditioner.
24 
25     Between the calls to PetscViewerGetSubViewer() and PetscViewerRestoreSubViewer() the original
26     viewer should not be used
27 
28     PETSCVIEWERDRAW and PETSCVIEWERBINARY only support returning a singleton viewer on rank 0,
29     all other ranks will return a NULL viewer
30 
31   Developer Notes:
32     There is currently incomplete error checking that the user does not use the original viewer between the
33     the calls to PetscViewerGetSubViewer() and PetscViewerRestoreSubViewer(). If the user does there
34     could be errors in the viewing that go undetected or crash the code.
35 
36    Concepts: PetscViewer^sequential version
37 
38 .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerRestoreSubViewer()
39 @*/
40 PetscErrorCode  PetscViewerGetSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
41 {
42   PetscErrorCode ierr;
43   PetscMPIInt    size;
44 
45   PetscFunctionBegin;
46   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
47   PetscValidPointer(outviewer,2);
48   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
49   if (size == 1) {
50     ierr       = PetscObjectReference((PetscObject)viewer);CHKERRQ(ierr);
51     *outviewer = viewer;
52   } else if (viewer->ops->getsubviewer) {
53     ierr = (*viewer->ops->getsubviewer)(viewer,comm,outviewer);CHKERRQ(ierr);
54   } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get SubViewer PetscViewer for type %s",((PetscObject)viewer)->type_name);
55   PetscFunctionReturn(0);
56 }
57 
58 /*@C
59    PetscViewerRestoreSubViewer - Restores a new PetscViewer obtained with PetscViewerGetSubViewer().
60 
61     Collective on PetscViewer
62 
63    Input Parameters:
64 +  viewer - the PetscViewer that was reproduced
65 -  outviewer - new PetscViewer
66 
67    Level: advanced
68 
69    Notes:
70     Call PetscViewerGetSubViewer() to get this PetscViewer, NOT PetscViewerCreate()
71 
72 .seealso: PetscViewerSocketOpen(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(), PetscViewerGetSubViewer()
73 @*/
74 PetscErrorCode  PetscViewerRestoreSubViewer(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
75 {
76   PetscErrorCode ierr;
77   PetscMPIInt    size;
78 
79   PetscFunctionBegin;
80   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
81 
82   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)viewer),&size);CHKERRQ(ierr);
83   if (size == 1) {
84     ierr = PetscObjectDereference((PetscObject)viewer);CHKERRQ(ierr);
85     if (outviewer) *outviewer = NULL;
86   } else if (viewer->ops->restoresubviewer) {
87     ierr = (*viewer->ops->restoresubviewer)(viewer,comm,outviewer);CHKERRQ(ierr);
88   }
89   PetscFunctionReturn(0);
90 }
91 
92