Commits

Jed Brown committed 668511f Merge

Merge branch 'rmills/dmshell'

* 'rmills/dmshell' of bitbucket:petsc/petsc:
Fix potential memory leak when re-setting VecScatters within a DMShell.
DMShellSetGlobalToLocalVecScatter() and DMShellSetLocalToGlobalVecScatter() now take a VecScatter instead of a VecScatter*.
ops->localtoglobalbegin/end now assigned appropriately in DMCreate_Shell().
Added DMLocalToGlobalBegin/EndDefaultShell().
Added DMShellSetLocalToGlobalVecScatter().

  • Participants
  • Parent commits ba8f9f4, d885d19

Comments (0)

Files changed (2)

File include/petscdmshell.h

 PETSC_EXTERN PetscErrorCode DMShellSetCreateGlobalVector(DM,PetscErrorCode (*)(DM,Vec*));
 PETSC_EXTERN PetscErrorCode DMShellSetCreateLocalVector(DM,PetscErrorCode (*)(DM,Vec*));
 PETSC_EXTERN PetscErrorCode DMShellSetGlobalToLocal(DM,PetscErrorCode (*)(DM,Vec,InsertMode,Vec),PetscErrorCode (*)(DM,Vec,InsertMode,Vec));
-PETSC_EXTERN PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM,VecScatter*);
+PETSC_EXTERN PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM,VecScatter);
 PETSC_EXTERN PetscErrorCode DMShellSetLocalToGlobal(DM,PetscErrorCode (*)(DM,Vec,InsertMode,Vec),PetscErrorCode (*)(DM,Vec,InsertMode,Vec));
+PETSC_EXTERN PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM,VecScatter);
 PETSC_EXTERN PetscErrorCode DMShellSetCreateMatrix(DM,PetscErrorCode (*)(DM,MatType,Mat*));
 PETSC_EXTERN PetscErrorCode DMGlobalToLocalBeginDefaultShell(DM,Vec,InsertMode,Vec);
 PETSC_EXTERN PetscErrorCode DMGlobalToLocalEndDefaultShell(DM,Vec,InsertMode,Vec);
+PETSC_EXTERN PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM,Vec,InsertMode,Vec);
+PETSC_EXTERN PetscErrorCode DMLocalToGlobalEndDefaultShell(DM,Vec,InsertMode,Vec);
 
 #endif

File src/dm/impls/shell/dmshell.c

   Vec        Xglobal;
   Vec        Xlocal;
   Mat        A;
-  VecScatter *gtol;
-  VecScatter *ltog;
+  VecScatter gtol;
+  VecScatter ltog;
 } DM_Shell;
 
 #undef __FUNCT__
 
   PetscFunctionBegin;
   if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
-  ierr = VecScatterBegin(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
+  ierr = VecScatterBegin(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
 
   PetscFunctionBegin;
    if (!shell->gtol) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetGlobalToLocalVecScatter()");
-  ierr = VecScatterEnd(*(shell->gtol),g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
+  ierr = VecScatterEnd(shell->gtol,g,l,mode,SCATTER_FORWARD);CHKERRQ(ierr);
   PetscFunctionReturn(0);
 }
 
 #undef __FUNCT__
+#define __FUNCT__ "DMLocalToGlobalBeginDefaultShell"
+/*@
+   DMLocalToGlobalBeginDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to begin a local to global scatter
+   Collective
+
+   Input Arguments:
++  dm - shell DM
+.  l - local vector
+.  mode - InsertMode
+-  g - global vector
+
+   Level: advanced
+
+   Note:  This is not normally called directly by user code, generally user code calls DMLocalToGlobalBegin() and DMLocalToGlobalEnd(). If the user provides their own custom routines to DMShellSetLocalToGlobal() then those routines might have reason to call this function. 
+
+.seealso: DMLocalToGlobalEndDefaultShell()
+@*/
+PetscErrorCode DMLocalToGlobalBeginDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
+{
+  PetscErrorCode ierr;
+  DM_Shell       *shell = (DM_Shell*)dm->data;
+
+  PetscFunctionBegin;
+  if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
+  ierr = VecScatterBegin(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
+#define __FUNCT__ "DMLocalToGlobalEndDefaultShell"
+/*@
+   DMLocalToGlobalEndDefaultShell - Uses the LocalToGlobal VecScatter context set by the user to end a local to global scatter
+   Collective
+
+   Input Arguments:
++  dm - shell DM
+.  l - local vector
+.  mode - InsertMode
+-  g - global vector
+
+   Level: advanced
+
+.seealso: DMLocalToGlobalBeginDefaultShell()
+@*/
+PetscErrorCode DMLocalToGlobalEndDefaultShell(DM dm,Vec l,InsertMode mode,Vec g)
+{
+  PetscErrorCode ierr;
+  DM_Shell       *shell = (DM_Shell*)dm->data;
+
+  PetscFunctionBegin;
+   if (!shell->ltog) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_WRONGSTATE, "Cannot be used without first setting the scatter context via DMShellSetLocalToGlobalVecScatter()");
+  ierr = VecScatterEnd(shell->ltog,l,g,mode,SCATTER_FORWARD);CHKERRQ(ierr);
+  PetscFunctionReturn(0);
+}
+
+
+#undef __FUNCT__
 #define __FUNCT__ "DMCreateMatrix_Shell"
 static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
 {
 
 .seealso: DMShellSetGlobalToLocal()
 @*/
-PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter *gtol)
+PetscErrorCode DMShellSetGlobalToLocalVecScatter(DM dm, VecScatter gtol)
 {
   DM_Shell       *shell = (DM_Shell*)dm->data;
+  PetscErrorCode ierr;
 
   PetscFunctionBegin;
+  ierr = PetscObjectReference((PetscObject)gtol);CHKERRQ(ierr);
+  /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
+  ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
   shell->gtol = gtol;
   PetscFunctionReturn(0);
 }
 
 #undef __FUNCT__
+#define __FUNCT__ "DMShellSetLocalToGlobalVecScatter"
+/*@
+   DMShellSetLocalToGlobalVecScatter - Sets a VecScatter context for local to global communication
+
+   Logically Collective on DM
+
+   Input Arguments
++  dm - the shell DM
+-  ltog - the local to global VecScatter context
+
+   Level: advanced
+
+.seealso: DMShellSetLocalToGlobal()
+@*/
+PetscErrorCode DMShellSetLocalToGlobalVecScatter(DM dm, VecScatter ltog)
+{
+  DM_Shell       *shell = (DM_Shell*)dm->data;
+  PetscErrorCode ierr;
+
+  PetscFunctionBegin;
+  ierr = PetscObjectReference((PetscObject)ltog);CHKERRQ(ierr);
+  /* Call VecScatterDestroy() to avoid a memory leak in case of re-setting. */
+  ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
+  shell->ltog = ltog;
+  PetscFunctionReturn(0);
+}
+
+#undef __FUNCT__
 #define __FUNCT__ "DMDestroy_Shell"
 static PetscErrorCode DMDestroy_Shell(DM dm)
 {
   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
+  ierr = VecScatterDestroy(&shell->gtol);CHKERRQ(ierr);
+  ierr = VecScatterDestroy(&shell->ltog);CHKERRQ(ierr);
   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
   ierr = PetscFree(shell);CHKERRQ(ierr);
   PetscFunctionReturn(0);
   dm->ops->load               = DMLoad_Shell;
   dm->ops->globaltolocalbegin = DMGlobalToLocalBeginDefaultShell;
   dm->ops->globaltolocalend   = DMGlobalToLocalEndDefaultShell;
+  dm->ops->localtoglobalbegin = DMLocalToGlobalBeginDefaultShell;
+  dm->ops->localtoglobalend   = DMLocalToGlobalEndDefaultShell;
   PetscFunctionReturn(0);
 }