Actual source code: dmshell.c

petsc-3.3-p5 2012-12-01
  1: #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
  2: #include <petscmat.h>           /*I    "petscmat.h"      I*/
  3: #include <petsc-private/dmimpl.h>     /*I    "petscdm.h"       I*/

  5: typedef struct  {
  6:   Vec Xglobal;
  7:   Mat A;
  8: } DM_Shell;

 12: static PetscErrorCode DMCreateMatrix_Shell(DM dm,const MatType mtype,Mat *J)
 13: {
 15:   DM_Shell       *shell = (DM_Shell*)dm->data;
 16:   Mat            A;

 21:   A = shell->A;
 22:   if (!A) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetMatrix() or DMShellSetCreateMatrix()");
 23:   if (mtype) {
 24:     PetscBool flg;
 25:     PetscObjectTypeCompare((PetscObject)A,mtype,&flg);
 26:     if (!flg) SETERRQ2(((PetscObject)dm)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
 27:   }
 28:   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
 29:     PetscObjectReference((PetscObject)A);
 30:     MatZeroEntries(A);
 31:     *J = A;
 32:   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
 33:     MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);
 34:     MatZeroEntries(*J);
 35:   }
 36:   return(0);
 37: }

 41: PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
 42: {
 44:   DM_Shell       *shell = (DM_Shell*)dm->data;
 45:   Vec            X;

 50:   *gvec = 0;
 51:   X = shell->Xglobal;
 52:   if (!X) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
 53:   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
 54:     PetscObjectReference((PetscObject)X);
 55:     VecZeroEntries(X);
 56:     *gvec = X;
 57:   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
 58:     VecDuplicate(X,gvec);
 59:     VecZeroEntries(*gvec);
 60:   }
 61:   PetscObjectCompose((PetscObject)*gvec,"DM",(PetscObject)dm);
 62:   return(0);
 63: }

 67: /*@
 68:    DMShellSetMatrix - sets a template matrix associated with the DMShell

 70:    Collective

 72:    Input Arguments:
 73: +  dm - shell DM
 74: -  J - template matrix

 76:    Level: advanced

 78: .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
 79: @*/
 80: PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
 81: {
 82:   DM_Shell *shell = (DM_Shell*)dm->data;
 84:   PetscBool isshell;

 89:   PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);
 90:   if (!isshell) return(0);
 91:   PetscObjectReference((PetscObject)J);
 92:   MatDestroy(&shell->A);
 93:   shell->A = J;
 94:   return(0);
 95: }

 99: /*@C
100:    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM

102:    Logically Collective on DM

104:    Input Arguments:
105: +  dm - the shell DM
106: -  func - the function to create a matrix

108:    Level: advanced

110: .seealso: DMCreateMatrix(), DMShellSetMatrix()
111: @*/
112: PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,const MatType,Mat*))
113: {

117:   dm->ops->creatematrix = func;
118:   return(0);
119: }

123: /*@
124:    DMShellSetGlobalVector - sets a template global vector associated with the DMShell

126:    Logically Collective on DM

128:    Input Arguments:
129: +  dm - shell DM
130: -  X - template vector

132:    Level: advanced

134: .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
135: @*/
136: PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
137: {
138:   DM_Shell *shell = (DM_Shell*)dm->data;
140:   PetscBool isshell;

145:   PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);
146:   if (!isshell) return(0);
147:   PetscObjectReference((PetscObject)X);
148:   VecDestroy(&shell->Xglobal);
149:   shell->Xglobal = X;
150:   return(0);
151: }

155: /*@C
156:    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM

158:    Logically Collective

160:    Input Arguments:
161: +  dm - the shell DM
162: -  func - the creation routine

164:    Level: advanced

166: .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
167: @*/
168: PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
169: {

173:   dm->ops->createglobalvector = func;
174:   return(0);
175: }

179: static PetscErrorCode DMDestroy_Shell(DM dm)
180: {
182:   DM_Shell       *shell = (DM_Shell*)dm->data;

185:   MatDestroy(&shell->A);
186:   VecDestroy(&shell->Xglobal);
187:   PetscFree(dm->data);
188:   return(0);
189: }


195: {
197:   DM_Shell      *shell;

200:   PetscNewLog(dm,DM_Shell,&shell);
201:   dm->data = shell;

203:   PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);
204:   dm->ops->destroy            = DMDestroy_Shell;
205:   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
206:   dm->ops->creatematrix       = DMCreateMatrix_Shell;
207:   return(0);
208: }

212: /*@
213:     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data

215:     Collective on MPI_Comm

217:     Input Parameter:
218: .   comm - the processors that will share the global vector

220:     Output Parameters:
221: .   shell - the shell DM

223:     Level: advanced

225: .seealso DMDestroy(), DMCreateGlobalVector()
226: @*/
227: PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
228: {

233:   DMCreate(comm,dm);
234:   DMSetType(*dm,DMSHELL);
235:   return(0);
236: }