Date: 2022-08-02T03:13:17+00:00

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: }