xref: /petsc/src/dm/impls/shell/dmshell.c (revision dc43b69e31d526194f6c418f7cc4be995f9d62c4)
1fe1899a2SJed Brown #include <petscdmshell.h>       /*I    "petscdmshell.h"  I*/
207475bc1SBarry Smith #include <petscmat.h>
307475bc1SBarry Smith #include <petsc-private/dmimpl.h>
4fe1899a2SJed Brown 
5fe1899a2SJed Brown typedef struct  {
6fe1899a2SJed Brown   Vec Xglobal;
7*dc43b69eSJed Brown   Vec Xlocal;
8fe1899a2SJed Brown   Mat A;
9fe1899a2SJed Brown } DM_Shell;
10fe1899a2SJed Brown 
11fe1899a2SJed Brown #undef __FUNCT__
12fe1899a2SJed Brown #define __FUNCT__ "DMCreateMatrix_Shell"
1319fd82e9SBarry Smith static PetscErrorCode DMCreateMatrix_Shell(DM dm,MatType mtype,Mat *J)
14fe1899a2SJed Brown {
15fe1899a2SJed Brown   PetscErrorCode ierr;
16fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
17fe1899a2SJed Brown   Mat            A;
18fe1899a2SJed Brown 
19fe1899a2SJed Brown   PetscFunctionBegin;
20fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
21fe1899a2SJed Brown   PetscValidPointer(J,3);
227bde9f88SJed Brown   if (!shell->A) {
237bde9f88SJed Brown     if (shell->Xglobal) {
247bde9f88SJed Brown       PetscInt m,M;
257bde9f88SJed Brown       ierr = PetscInfo(dm,"Naively creating matrix using global vector distribution without preallocation");CHKERRQ(ierr);
267bde9f88SJed Brown       ierr = VecGetSize(shell->Xglobal,&M);CHKERRQ(ierr);
277bde9f88SJed Brown       ierr = VecGetLocalSize(shell->Xglobal,&m);CHKERRQ(ierr);
287bde9f88SJed Brown       ierr = MatCreate(((PetscObject)dm)->comm,&shell->A);CHKERRQ(ierr);
297bde9f88SJed Brown       ierr = MatSetSizes(shell->A,m,m,M,M);CHKERRQ(ierr);
307bde9f88SJed Brown       if (mtype) {ierr = MatSetType(shell->A,mtype);CHKERRQ(ierr);}
317bde9f88SJed Brown       ierr = MatSetUp(shell->A);CHKERRQ(ierr);
327bde9f88SJed Brown     } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetMatrix(), DMShellSetCreateMatrix(), or provide a vector");
337bde9f88SJed Brown   }
34fe1899a2SJed Brown   A = shell->A;
35ad6bc421SBarry Smith   /* the check below is tacky and incomplete */
36fe1899a2SJed Brown   if (mtype) {
37ad6bc421SBarry Smith     PetscBool flg,aij,seqaij,mpiaij;
38251f4c67SDmitry Karpeev     ierr = PetscObjectTypeCompare((PetscObject)A,mtype,&flg);CHKERRQ(ierr);
39ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&seqaij);CHKERRQ(ierr);
40ad6bc421SBarry Smith     ierr = PetscObjectTypeCompare((PetscObject)A,MATMPIAIJ,&mpiaij);CHKERRQ(ierr);
41ad6bc421SBarry Smith     ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
42ad6bc421SBarry Smith     if (!flg) {
43ad6bc421SBarry Smith       if (!(aij & (seqaij || mpiaij))) SETERRQ2(((PetscObject)dm)->comm,PETSC_ERR_ARG_NOTSAMETYPE,"Requested matrix of type %s, but only %s available",mtype,((PetscObject)A)->type_name);
44ad6bc421SBarry Smith     }
45fe1899a2SJed Brown   }
46fe1899a2SJed Brown   if (((PetscObject)A)->refct < 2) { /* We have an exclusive reference so we can give it out */
47fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr);
48fe1899a2SJed Brown     ierr = MatZeroEntries(A);CHKERRQ(ierr);
49fe1899a2SJed Brown     *J = A;
50fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
51fe1899a2SJed Brown     ierr = MatDuplicate(A,MAT_DO_NOT_COPY_VALUES,J);CHKERRQ(ierr);
52fe1899a2SJed Brown     ierr = MatZeroEntries(*J);CHKERRQ(ierr);
53fe1899a2SJed Brown   }
54fe1899a2SJed Brown   PetscFunctionReturn(0);
55fe1899a2SJed Brown }
56fe1899a2SJed Brown 
57fe1899a2SJed Brown #undef __FUNCT__
58fe1899a2SJed Brown #define __FUNCT__ "DMCreateGlobalVector_Shell"
59fe1899a2SJed Brown PetscErrorCode DMCreateGlobalVector_Shell(DM dm,Vec *gvec)
60fe1899a2SJed Brown {
61fe1899a2SJed Brown   PetscErrorCode ierr;
62fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
63fe1899a2SJed Brown   Vec            X;
64fe1899a2SJed Brown 
65fe1899a2SJed Brown   PetscFunctionBegin;
66fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
67fe1899a2SJed Brown   PetscValidPointer(gvec,2);
68fe1899a2SJed Brown   *gvec = 0;
69fe1899a2SJed Brown   X = shell->Xglobal;
708c87107bSJed Brown   if (!X) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetGlobalVector() or DMShellSetCreateGlobalVector()");
71fe1899a2SJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
72fe1899a2SJed Brown     ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
73fe1899a2SJed Brown     ierr = VecZeroEntries(X);CHKERRQ(ierr);
74fe1899a2SJed Brown     *gvec = X;
75fe1899a2SJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
76fe1899a2SJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
77fe1899a2SJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
78fe1899a2SJed Brown   }
79c688c046SMatthew G Knepley   ierr = VecSetDM(*gvec,dm);CHKERRQ(ierr);
80fe1899a2SJed Brown   PetscFunctionReturn(0);
81fe1899a2SJed Brown }
82fe1899a2SJed Brown 
83fe1899a2SJed Brown #undef __FUNCT__
84*dc43b69eSJed Brown #define __FUNCT__ "DMCreateLocalVector_Shell"
85*dc43b69eSJed Brown PetscErrorCode DMCreateLocalVector_Shell(DM dm,Vec *gvec)
86*dc43b69eSJed Brown {
87*dc43b69eSJed Brown   PetscErrorCode ierr;
88*dc43b69eSJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
89*dc43b69eSJed Brown   Vec            X;
90*dc43b69eSJed Brown 
91*dc43b69eSJed Brown   PetscFunctionBegin;
92*dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
93*dc43b69eSJed Brown   PetscValidPointer(gvec,2);
94*dc43b69eSJed Brown   *gvec = 0;
95*dc43b69eSJed Brown   X = shell->Xlocal;
96*dc43b69eSJed Brown   if (!X) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_USER,"Must call DMShellSetLocalVector() or DMShellSetCreateLocalVector()");
97*dc43b69eSJed Brown   if (((PetscObject)X)->refct < 2) { /* We have an exclusive reference so we can give it out */
98*dc43b69eSJed Brown     ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
99*dc43b69eSJed Brown     ierr = VecZeroEntries(X);CHKERRQ(ierr);
100*dc43b69eSJed Brown     *gvec = X;
101*dc43b69eSJed Brown   } else {                      /* Need to create a copy, could use MAT_SHARE_NONZERO_PATTERN in most cases */
102*dc43b69eSJed Brown     ierr = VecDuplicate(X,gvec);CHKERRQ(ierr);
103*dc43b69eSJed Brown     ierr = VecZeroEntries(*gvec);CHKERRQ(ierr);
104*dc43b69eSJed Brown   }
105*dc43b69eSJed Brown   PetscFunctionReturn(0);
106*dc43b69eSJed Brown }
107*dc43b69eSJed Brown 
108*dc43b69eSJed Brown #undef __FUNCT__
109fe1899a2SJed Brown #define __FUNCT__ "DMShellSetMatrix"
110fe1899a2SJed Brown /*@
111fe1899a2SJed Brown    DMShellSetMatrix - sets a template matrix associated with the DMShell
112fe1899a2SJed Brown 
113fe1899a2SJed Brown    Collective
114fe1899a2SJed Brown 
115fe1899a2SJed Brown    Input Arguments:
116fe1899a2SJed Brown +  dm - shell DM
117fe1899a2SJed Brown -  J - template matrix
118fe1899a2SJed Brown 
119fe1899a2SJed Brown    Level: advanced
120fe1899a2SJed Brown 
121fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetCreateMatrix()
122fe1899a2SJed Brown @*/
123fe1899a2SJed Brown PetscErrorCode DMShellSetMatrix(DM dm,Mat J)
124fe1899a2SJed Brown {
125fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell*)dm->data;
126fe1899a2SJed Brown   PetscErrorCode ierr;
1278c87107bSJed Brown   PetscBool isshell;
128fe1899a2SJed Brown 
129fe1899a2SJed Brown   PetscFunctionBegin;
1308c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1318c87107bSJed Brown   PetscValidHeaderSpecific(J,MAT_CLASSID,2);
132251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1338c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
134fe1899a2SJed Brown   ierr = PetscObjectReference((PetscObject)J);CHKERRQ(ierr);
135fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
136fe1899a2SJed Brown   shell->A = J;
137fe1899a2SJed Brown   PetscFunctionReturn(0);
138fe1899a2SJed Brown }
139fe1899a2SJed Brown 
140fe1899a2SJed Brown #undef __FUNCT__
141fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateMatrix"
142fe1899a2SJed Brown /*@C
143fe1899a2SJed Brown    DMShellSetCreateMatrix - sets the routine to create a matrix associated with the shell DM
144fe1899a2SJed Brown 
145fe1899a2SJed Brown    Logically Collective on DM
146fe1899a2SJed Brown 
147fe1899a2SJed Brown    Input Arguments:
148fe1899a2SJed Brown +  dm - the shell DM
149fe1899a2SJed Brown -  func - the function to create a matrix
150fe1899a2SJed Brown 
151fe1899a2SJed Brown    Level: advanced
152fe1899a2SJed Brown 
153fe1899a2SJed Brown .seealso: DMCreateMatrix(), DMShellSetMatrix()
154fe1899a2SJed Brown @*/
15519fd82e9SBarry Smith PetscErrorCode DMShellSetCreateMatrix(DM dm,PetscErrorCode (*func)(DM,MatType,Mat*))
156fe1899a2SJed Brown {
157fe1899a2SJed Brown 
158fe1899a2SJed Brown   PetscFunctionBegin;
159fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
160fe1899a2SJed Brown   dm->ops->creatematrix = func;
161fe1899a2SJed Brown   PetscFunctionReturn(0);
162fe1899a2SJed Brown }
163fe1899a2SJed Brown 
164fe1899a2SJed Brown #undef __FUNCT__
165fe1899a2SJed Brown #define __FUNCT__ "DMShellSetGlobalVector"
166fe1899a2SJed Brown /*@
167fe1899a2SJed Brown    DMShellSetGlobalVector - sets a template global vector associated with the DMShell
168fe1899a2SJed Brown 
169fe1899a2SJed Brown    Logically Collective on DM
170fe1899a2SJed Brown 
171fe1899a2SJed Brown    Input Arguments:
172fe1899a2SJed Brown +  dm - shell DM
173fe1899a2SJed Brown -  X - template vector
174fe1899a2SJed Brown 
175fe1899a2SJed Brown    Level: advanced
176fe1899a2SJed Brown 
177fe1899a2SJed Brown .seealso: DMCreateGlobalVector(), DMShellSetMatrix(), DMShellSetCreateGlobalVector()
178fe1899a2SJed Brown @*/
179fe1899a2SJed Brown PetscErrorCode DMShellSetGlobalVector(DM dm,Vec X)
180fe1899a2SJed Brown {
181fe1899a2SJed Brown   DM_Shell *shell = (DM_Shell*)dm->data;
182fe1899a2SJed Brown   PetscErrorCode ierr;
1838c87107bSJed Brown   PetscBool isshell;
184fe1899a2SJed Brown 
185fe1899a2SJed Brown   PetscFunctionBegin;
1868c87107bSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
1878c87107bSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
188251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
1898c87107bSJed Brown   if (!isshell) PetscFunctionReturn(0);
190fe1899a2SJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
191fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
192fe1899a2SJed Brown   shell->Xglobal = X;
193fe1899a2SJed Brown   PetscFunctionReturn(0);
194fe1899a2SJed Brown }
195fe1899a2SJed Brown 
196fe1899a2SJed Brown #undef __FUNCT__
197fe1899a2SJed Brown #define __FUNCT__ "DMShellSetCreateGlobalVector"
198fe1899a2SJed Brown /*@C
199fe1899a2SJed Brown    DMShellSetCreateGlobalVector - sets the routine to create a global vector associated with the shell DM
200fe1899a2SJed Brown 
201fe1899a2SJed Brown    Logically Collective
202fe1899a2SJed Brown 
203fe1899a2SJed Brown    Input Arguments:
204fe1899a2SJed Brown +  dm - the shell DM
205fe1899a2SJed Brown -  func - the creation routine
206fe1899a2SJed Brown 
207fe1899a2SJed Brown    Level: advanced
208fe1899a2SJed Brown 
209fe1899a2SJed Brown .seealso: DMShellSetGlobalVector(), DMShellSetCreateMatrix()
210fe1899a2SJed Brown @*/
211fe1899a2SJed Brown PetscErrorCode DMShellSetCreateGlobalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
212fe1899a2SJed Brown {
213fe1899a2SJed Brown 
214fe1899a2SJed Brown   PetscFunctionBegin;
215fe1899a2SJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
216fe1899a2SJed Brown   dm->ops->createglobalvector = func;
217fe1899a2SJed Brown   PetscFunctionReturn(0);
218fe1899a2SJed Brown }
219fe1899a2SJed Brown 
220fe1899a2SJed Brown #undef __FUNCT__
221*dc43b69eSJed Brown #define __FUNCT__ "DMShellSetLocalVector"
222*dc43b69eSJed Brown /*@
223*dc43b69eSJed Brown    DMShellSetLocalVector - sets a template local vector associated with the DMShell
224*dc43b69eSJed Brown 
225*dc43b69eSJed Brown    Logically Collective on DM
226*dc43b69eSJed Brown 
227*dc43b69eSJed Brown    Input Arguments:
228*dc43b69eSJed Brown +  dm - shell DM
229*dc43b69eSJed Brown -  X - template vector
230*dc43b69eSJed Brown 
231*dc43b69eSJed Brown    Level: advanced
232*dc43b69eSJed Brown 
233*dc43b69eSJed Brown .seealso: DMCreateLocalVector(), DMShellSetMatrix(), DMShellSetCreateLocalVector()
234*dc43b69eSJed Brown @*/
235*dc43b69eSJed Brown PetscErrorCode DMShellSetLocalVector(DM dm,Vec X)
236*dc43b69eSJed Brown {
237*dc43b69eSJed Brown   DM_Shell *shell = (DM_Shell*)dm->data;
238*dc43b69eSJed Brown   PetscErrorCode ierr;
239*dc43b69eSJed Brown   PetscBool isshell;
240*dc43b69eSJed Brown 
241*dc43b69eSJed Brown   PetscFunctionBegin;
242*dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
243*dc43b69eSJed Brown   PetscValidHeaderSpecific(X,VEC_CLASSID,2);
244*dc43b69eSJed Brown   ierr = PetscObjectTypeCompare((PetscObject)dm,DMSHELL,&isshell);CHKERRQ(ierr);
245*dc43b69eSJed Brown   if (!isshell) PetscFunctionReturn(0);
246*dc43b69eSJed Brown   ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr);
247*dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
248*dc43b69eSJed Brown   shell->Xlocal = X;
249*dc43b69eSJed Brown   PetscFunctionReturn(0);
250*dc43b69eSJed Brown }
251*dc43b69eSJed Brown 
252*dc43b69eSJed Brown #undef __FUNCT__
253*dc43b69eSJed Brown #define __FUNCT__ "DMShellSetCreateLocalVector"
254*dc43b69eSJed Brown /*@C
255*dc43b69eSJed Brown    DMShellSetCreateLocalVector - sets the routine to create a local vector associated with the shell DM
256*dc43b69eSJed Brown 
257*dc43b69eSJed Brown    Logically Collective
258*dc43b69eSJed Brown 
259*dc43b69eSJed Brown    Input Arguments:
260*dc43b69eSJed Brown +  dm - the shell DM
261*dc43b69eSJed Brown -  func - the creation routine
262*dc43b69eSJed Brown 
263*dc43b69eSJed Brown    Level: advanced
264*dc43b69eSJed Brown 
265*dc43b69eSJed Brown .seealso: DMShellSetLocalVector(), DMShellSetCreateMatrix()
266*dc43b69eSJed Brown @*/
267*dc43b69eSJed Brown PetscErrorCode DMShellSetCreateLocalVector(DM dm,PetscErrorCode (*func)(DM,Vec*))
268*dc43b69eSJed Brown {
269*dc43b69eSJed Brown 
270*dc43b69eSJed Brown   PetscFunctionBegin;
271*dc43b69eSJed Brown   PetscValidHeaderSpecific(dm,DM_CLASSID,1);
272*dc43b69eSJed Brown   dm->ops->createlocalvector = func;
273*dc43b69eSJed Brown   PetscFunctionReturn(0);
274*dc43b69eSJed Brown }
275*dc43b69eSJed Brown 
276*dc43b69eSJed Brown #undef __FUNCT__
277fe1899a2SJed Brown #define __FUNCT__ "DMDestroy_Shell"
278fe1899a2SJed Brown static PetscErrorCode DMDestroy_Shell(DM dm)
279fe1899a2SJed Brown {
280fe1899a2SJed Brown   PetscErrorCode ierr;
281fe1899a2SJed Brown   DM_Shell       *shell = (DM_Shell*)dm->data;
282fe1899a2SJed Brown 
283fe1899a2SJed Brown   PetscFunctionBegin;
284fe1899a2SJed Brown   ierr = MatDestroy(&shell->A);CHKERRQ(ierr);
285fe1899a2SJed Brown   ierr = VecDestroy(&shell->Xglobal);CHKERRQ(ierr);
286*dc43b69eSJed Brown   ierr = VecDestroy(&shell->Xlocal);CHKERRQ(ierr);
2877b6ad80cSMatthew G Knepley   /* This was originally freed in DMDestroy(), but that prevents reference counting of backend objects */
2887b6ad80cSMatthew G Knepley   ierr = PetscFree(shell);CHKERRQ(ierr);
289fe1899a2SJed Brown   PetscFunctionReturn(0);
290fe1899a2SJed Brown }
291fe1899a2SJed Brown 
2922d53ad75SBarry Smith #undef __FUNCT__
2932d53ad75SBarry Smith #define __FUNCT__ "DMView_Shell"
2942d53ad75SBarry Smith static PetscErrorCode DMView_Shell(DM dm,PetscViewer v)
2952d53ad75SBarry Smith {
2962d53ad75SBarry Smith   PetscErrorCode ierr;
2972d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
2982d53ad75SBarry Smith 
2992d53ad75SBarry Smith   PetscFunctionBegin;
3002d53ad75SBarry Smith   ierr = VecView(shell->Xglobal,v);CHKERRQ(ierr);
3012d53ad75SBarry Smith   PetscFunctionReturn(0);
3022d53ad75SBarry Smith }
3032d53ad75SBarry Smith 
3042d53ad75SBarry Smith #undef __FUNCT__
3052d53ad75SBarry Smith #define __FUNCT__ "DMLoad_Shell"
3062d53ad75SBarry Smith static PetscErrorCode DMLoad_Shell(DM dm,PetscViewer v)
3072d53ad75SBarry Smith {
3082d53ad75SBarry Smith   PetscErrorCode ierr;
3092d53ad75SBarry Smith   DM_Shell       *shell = (DM_Shell*)dm->data;
3102d53ad75SBarry Smith 
3112d53ad75SBarry Smith   PetscFunctionBegin;
3122d53ad75SBarry Smith   ierr = VecCreate(((PetscObject)dm)->comm,&shell->Xglobal);CHKERRQ(ierr);
3132d53ad75SBarry Smith   ierr = VecLoad(shell->Xglobal,v);CHKERRQ(ierr);
3142d53ad75SBarry Smith   PetscFunctionReturn(0);
3152d53ad75SBarry Smith }
316fe1899a2SJed Brown 
317fe1899a2SJed Brown #undef __FUNCT__
318fe1899a2SJed Brown #define __FUNCT__ "DMCreate_Shell"
3198c87107bSJed Brown PETSC_EXTERN_C PetscErrorCode  DMCreate_Shell(DM dm)
320fe1899a2SJed Brown {
321fe1899a2SJed Brown   PetscErrorCode ierr;
322fe1899a2SJed Brown   DM_Shell      *shell;
323fe1899a2SJed Brown 
324fe1899a2SJed Brown   PetscFunctionBegin;
3258c87107bSJed Brown   ierr = PetscNewLog(dm,DM_Shell,&shell);CHKERRQ(ierr);
3268c87107bSJed Brown   dm->data = shell;
327fe1899a2SJed Brown 
3288c87107bSJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)dm,DMSHELL);CHKERRQ(ierr);
3298c87107bSJed Brown   dm->ops->destroy            = DMDestroy_Shell;
3308c87107bSJed Brown   dm->ops->createglobalvector = DMCreateGlobalVector_Shell;
331*dc43b69eSJed Brown   dm->ops->createlocalvector  = DMCreateLocalVector_Shell;
3328c87107bSJed Brown   dm->ops->creatematrix       = DMCreateMatrix_Shell;
3332d53ad75SBarry Smith   dm->ops->view               = DMView_Shell;
3342d53ad75SBarry Smith   dm->ops->load               = DMLoad_Shell;
335fe1899a2SJed Brown   PetscFunctionReturn(0);
336fe1899a2SJed Brown }
337fe1899a2SJed Brown 
338fe1899a2SJed Brown #undef __FUNCT__
339fe1899a2SJed Brown #define __FUNCT__ "DMShellCreate"
340fe1899a2SJed Brown /*@
341fe1899a2SJed Brown     DMShellCreate - Creates a shell DM object, used to manage user-defined problem data
342fe1899a2SJed Brown 
343fe1899a2SJed Brown     Collective on MPI_Comm
344fe1899a2SJed Brown 
345fe1899a2SJed Brown     Input Parameter:
346fe1899a2SJed Brown .   comm - the processors that will share the global vector
347fe1899a2SJed Brown 
348fe1899a2SJed Brown     Output Parameters:
349fe1899a2SJed Brown .   shell - the shell DM
350fe1899a2SJed Brown 
351fe1899a2SJed Brown     Level: advanced
352fe1899a2SJed Brown 
353*dc43b69eSJed Brown .seealso DMDestroy(), DMCreateGlobalVector(), DMCreateLocalVector()
354fe1899a2SJed Brown @*/
355fe1899a2SJed Brown PetscErrorCode  DMShellCreate(MPI_Comm comm,DM *dm)
356fe1899a2SJed Brown {
357fe1899a2SJed Brown   PetscErrorCode ierr;
358fe1899a2SJed Brown 
359fe1899a2SJed Brown   PetscFunctionBegin;
360fe1899a2SJed Brown   PetscValidPointer(dm,2);
361fe1899a2SJed Brown   ierr = DMCreate(comm,dm);CHKERRQ(ierr);
362fe1899a2SJed Brown   ierr = DMSetType(*dm,DMSHELL);CHKERRQ(ierr);
363fe1899a2SJed Brown   PetscFunctionReturn(0);
364fe1899a2SJed Brown }
365